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