1
- import {
2
- DEFAULT_MEDIA_TYPE ,
3
- getJSDoc ,
4
- getKindValue ,
5
- getResponseTypeFromMediaType ,
6
- getSafePropertyName ,
7
- getTypeName ,
8
- getURL ,
9
- HTTPMethod ,
10
- SUCCESSFUL_CODES ,
11
- XHRResponseType ,
12
- } from '../../common/utils' ;
1
+ import { getJSDoc , getKindValue , getSafePropertyName , getTypeName , getURL , HTTPMethod } from '../../common/utils' ;
13
2
import {
14
3
getSerializedPropertyType ,
15
4
getSerializedObjectType ,
@@ -45,8 +34,8 @@ import { ResolveRefContext, fromString, getRelativePath, Ref } from '../../../..
45
34
import { OperationObject } from '../../../../schema/3.0/operation-object' ;
46
35
import { ParameterObject , ParameterObjectCodec } from '../../../../schema/3.0/parameter-object' ;
47
36
import { RequestBodyObjectCodec } from '../../../../schema/3.0/request-body-object' ;
48
- import { chain , isSome , none , Option , some , map , fromEither , getOrElse , fold } from 'fp-ts/lib/Option' ;
49
- import { constFalse } from 'fp-ts/lib/function' ;
37
+ import { chain , isSome , none , Option , some , map , fromEither , fold } from 'fp-ts/lib/Option' ;
38
+ import { constFalse , flow } from 'fp-ts/lib/function' ;
50
39
import { clientRef } from '../../common/bundled/client' ;
51
40
import { Kind } from '../../../../utils/types' ;
52
41
import { ReferenceObjectCodec } from '../../../../schema/3.0/reference-object' ;
@@ -60,16 +49,13 @@ import {
60
49
SerializedFragment ,
61
50
} from '../../common/data/serialized-fragment' ;
62
51
import { SchemaObjectCodec } from '../../../../schema/3.0/schema-object' ;
63
- import { lookup } from 'fp-ts/lib/Record' ;
64
- import { ResponseObjectCodec } from '../../../../schema/3.0/response-object' ;
65
52
import {
66
53
fromSerializedHeaderParameter ,
67
54
getSerializedHeaderParameterType ,
68
55
SerializedHeaderParameter ,
69
56
} from '../../common/data/serialized-header-parameters' ;
70
- import { getResponseMedia } from './response-object' ;
71
57
72
- const getOperationName = ( pattern : string , operation : OperationObject , method : HTTPMethod ) : string =>
58
+ export const getOperationName = ( pattern : string , operation : OperationObject , method : HTTPMethod ) : string =>
73
59
pipe (
74
60
operation . operationId ,
75
61
option . getOrElse ( ( ) => `${ method } _${ getSafePropertyName ( pattern ) } ` ) ,
@@ -289,20 +275,6 @@ export const serializeOperationObject = combineReader(
289
275
) ;
290
276
291
277
const serializedResponses = serializeResponsesObject ( from ) ( operation . responses ) ;
292
- const mediaType : string = pipe (
293
- SUCCESSFUL_CODES ,
294
- array . findFirstMap ( code => lookup ( code , operation . responses ) ) ,
295
- chain ( response =>
296
- ReferenceObjectCodec . is ( response )
297
- ? fromEither ( e . resolveRef ( response . $ref , ResponseObjectCodec ) )
298
- : some ( response ) ,
299
- ) ,
300
- chain ( response => response . content ) ,
301
- chain ( getResponseMedia ) ,
302
- map ( ( { key } ) => key ) ,
303
- getOrElse ( ( ) => DEFAULT_MEDIA_TYPE ) ,
304
- ) ;
305
- const responseType : XHRResponseType = getResponseTypeFromMediaType ( mediaType ) ;
306
278
const serializedContentType = pipe (
307
279
operation . requestBody ,
308
280
chain ( requestBody =>
@@ -318,10 +290,6 @@ export const serializeOperationObject = combineReader(
318
290
contentType => `'Content-type': '${ contentType } ',` ,
319
291
) ,
320
292
) ;
321
- const requestHeaders = `{
322
- Accept: '${ mediaType } ',
323
- ${ serializedContentType }
324
- }` ;
325
293
326
294
return combineEither (
327
295
parameters ,
@@ -332,6 +300,7 @@ export const serializeOperationObject = combineReader(
332
300
const hasBodyParameter = isSome ( parameters . serializedBodyParameter ) ;
333
301
const hasHeaderParameters = isSome ( parameters . serializedHeadersParameter ) ;
334
302
const hasParameters = hasQueryParameters || hasBodyParameter || hasHeaderParameters ;
303
+ const hasResponseMap = either . isRight ( serializedResponses ) ;
335
304
336
305
const bodyType = pipe (
337
306
parameters . serializedBodyParameter ,
@@ -346,7 +315,7 @@ export const serializeOperationObject = combineReader(
346
315
347
316
const queryType = pipe (
348
317
parameters . serializedQueryParameter ,
349
- option . map ( query => `query: ${ query . type } , ` ) ,
318
+ option . map ( query => `query: ${ query . type } ; ` ) ,
350
319
option . getOrElse ( ( ) => '' ) ,
351
320
) ;
352
321
const queryIO = pipe (
@@ -357,7 +326,7 @@ export const serializeOperationObject = combineReader(
357
326
358
327
const headersType = pipe (
359
328
parameters . serializedHeadersParameter ,
360
- option . map ( headers => `headers: ${ headers . type } ` ) ,
329
+ option . map ( headers => `headers: ${ headers . type } ; ` ) ,
361
330
option . getOrElse ( ( ) => '' ) ,
362
331
) ;
363
332
@@ -366,43 +335,102 @@ export const serializeOperationObject = combineReader(
366
335
option . map ( headers => `const headers = ${ headers . io } .encode(parameters.headers)` ) ,
367
336
option . getOrElse ( ( ) => '' ) ,
368
337
) ;
338
+ const accepArg = hasResponseMap ? 'accept?: A;' : '' ;
369
339
370
340
const argsType = concatIf (
371
- hasParameters ,
341
+ hasParameters || hasResponseMap ,
372
342
parameters . serializedPathParameters . map ( p => p . type ) ,
373
- [ `parameters: { ${ queryType } ${ bodyType } ${ headersType } }` ] ,
343
+ [ `parameters${ hasParameters ? '' : '?' } : { ${ queryType } ${ bodyType } ${ headersType } ${ accepArg } }` ] ,
374
344
) . join ( ',' ) ;
375
345
376
- const type = `
346
+ const type = pipe (
347
+ serializedResponses ,
348
+ either . fold (
349
+ sr => `
377
350
${ getJSDoc ( array . compact ( [ deprecated , operation . summary ] ) ) }
378
- readonly ${ operationName } : (${ argsType } ) => ${ getKindValue ( kind , serializedResponses . type ) } ;
379
- ` ;
351
+ readonly ${ operationName } : (${ argsType } ) => ${ getKindValue ( kind , sr . schema . type ) } ;
352
+ ` ,
353
+ sr => `
354
+ ${ getJSDoc ( array . compact ( [ deprecated , operation . summary ] ) ) }
355
+ readonly ${ operationName } : <A extends keyof MapToResponse${ operationName } = '${
356
+ sr [ 0 ] . mediaType
357
+ } '>(${ argsType } ) => ${ getKindValue ( kind , `MapToResponse${ operationName } [A]` ) } ;
358
+ ` ,
359
+ ) ,
360
+ ) ;
380
361
381
362
const argsIO = concatIf (
382
- hasParameters ,
363
+ hasParameters || hasResponseMap ,
383
364
parameters . pathParameters . map ( p => p . name ) ,
384
365
[ 'parameters' ] ,
385
366
) . join ( ',' ) ;
386
367
368
+ const decode = pipe (
369
+ serializedResponses ,
370
+ either . fold (
371
+ sr => `${ sr . schema . io } .decode(value)` ,
372
+ ( ) => `decode(accept, value)` ,
373
+ ) ,
374
+ ) ;
375
+ const acceptIO = pipe (
376
+ serializedResponses ,
377
+ either . fold (
378
+ sr => `const accept = '${ sr . mediaType } ';` ,
379
+ sr =>
380
+ `const rawAccept = (parameters && parameters.accept)!;
381
+ const accept = (rawAccept || '${ sr [ 0 ] . mediaType } ') as typeof rawAccept;` ,
382
+ ) ,
383
+ ) ;
384
+
385
+ const mapToIO = pipe (
386
+ serializedResponses ,
387
+ either . fold (
388
+ ( ) => '' ,
389
+ sr => {
390
+ const rows = sr . map ( s => `'${ s . mediaType } ': ${ s . schema . io } ` ) ;
391
+ return `const mapToIO = { ${ rows . join ( ) } };` ;
392
+ } ,
393
+ ) ,
394
+ ) ;
395
+
396
+ const decodeIO = pipe (
397
+ serializedResponses ,
398
+ either . fold (
399
+ ( ) => '' ,
400
+ ( ) =>
401
+ `const decode = <A extends keyof MapToResponse${ operationName } >(a: A, b: unknown) =>
402
+ (mapToIO[a].decode(b) as unknown) as Either<Errors, MapToResponse${ operationName } [A]>;` ,
403
+ ) ,
404
+ ) ;
405
+
406
+ const requestHeaders = `{
407
+ Accept: accept,
408
+ ${ serializedContentType }
409
+ }` ;
410
+
387
411
const io = `
388
412
${ operationName } : (${ argsIO } ) => {
389
413
${ bodyIO }
390
414
${ queryIO }
391
415
${ headersIO }
416
+ ${ acceptIO }
417
+ ${ mapToIO }
418
+ ${ decodeIO }
419
+ const responseType = getResponseTypeFromMediaType(accept);
392
420
const requestHeaders = ${ requestHeaders }
393
421
394
422
return e.httpClient.chain(
395
423
e.httpClient.request({
396
424
url: ${ getURL ( pattern , parameters . serializedPathParameters ) } ,
397
425
method: '${ method } ',
398
- responseType: ' ${ responseType } ' ,
426
+ responseType,
399
427
${ when ( hasQueryParameters , 'query,' ) }
400
428
${ when ( hasBodyParameter , 'body,' ) }
401
429
headers: {${ hasHeaderParameters ? '...headers,' : '' } ...requestHeaders}
402
430
}),
403
431
value =>
404
432
pipe(
405
- ${ serializedResponses . io } . decode(value) ,
433
+ ${ decode } ,
406
434
either.mapLeft(ResponseValidationError.create),
407
435
either.fold(error => e.httpClient.throwError(error), decoded => e.httpClient.of(decoded)),
408
436
),
@@ -411,11 +439,26 @@ export const serializeOperationObject = combineReader(
411
439
` ;
412
440
413
441
const dependencies = [
442
+ serializedDependency ( 'getResponseTypeFromMediaType' , '../utils/utils' ) ,
414
443
serializedDependency ( 'ResponseValidationError' , getRelativePath ( from , clientRef ) ) ,
415
444
serializedDependency ( 'pipe' , 'fp-ts/lib/pipeable' ) ,
416
445
serializedDependency ( 'either' , 'fp-ts' ) ,
417
446
getSerializedKindDependency ( kind ) ,
418
- ...serializedResponses . dependencies ,
447
+ ...pipe (
448
+ serializedResponses ,
449
+ either . fold (
450
+ s => s . schema . dependencies ,
451
+ flow (
452
+ array . map ( s => s . schema . dependencies ) ,
453
+ array . flatten ,
454
+ arr => [
455
+ ...arr ,
456
+ serializedDependency ( 'Errors' , 'io-ts' ) ,
457
+ serializedDependency ( 'Either' , 'fp-ts/lib/Either' ) ,
458
+ ] ,
459
+ ) ,
460
+ ) ,
461
+ ) ,
419
462
...array . flatten ( [
420
463
...parameters . serializedPathParameters . map ( p => p . dependencies ) ,
421
464
...array . compact ( [
0 commit comments