@azure-tools/typespec-go 0.10.7 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/codegen.go/src/core/clientFactory.d.ts.map +1 -1
  2. package/dist/codegen.go/src/core/clientFactory.js +18 -15
  3. package/dist/codegen.go/src/core/clientFactory.js.map +1 -1
  4. package/dist/codegen.go/src/core/cloudConfig.d.ts.map +1 -1
  5. package/dist/codegen.go/src/core/cloudConfig.js +4 -3
  6. package/dist/codegen.go/src/core/cloudConfig.js.map +1 -1
  7. package/dist/codegen.go/src/core/constants.d.ts.map +1 -1
  8. package/dist/codegen.go/src/core/constants.js +6 -4
  9. package/dist/codegen.go/src/core/constants.js.map +1 -1
  10. package/dist/codegen.go/src/core/example.js +51 -52
  11. package/dist/codegen.go/src/core/example.js.map +1 -1
  12. package/dist/codegen.go/src/core/helpers.d.ts +27 -11
  13. package/dist/codegen.go/src/core/helpers.d.ts.map +1 -1
  14. package/dist/codegen.go/src/core/helpers.js +56 -17
  15. package/dist/codegen.go/src/core/helpers.js.map +1 -1
  16. package/dist/codegen.go/src/core/interfaces.d.ts.map +1 -1
  17. package/dist/codegen.go/src/core/interfaces.js +4 -3
  18. package/dist/codegen.go/src/core/interfaces.js.map +1 -1
  19. package/dist/codegen.go/src/core/models.d.ts.map +1 -1
  20. package/dist/codegen.go/src/core/models.js +289 -230
  21. package/dist/codegen.go/src/core/models.js.map +1 -1
  22. package/dist/codegen.go/src/core/operations.d.ts.map +1 -1
  23. package/dist/codegen.go/src/core/operations.js +689 -407
  24. package/dist/codegen.go/src/core/operations.js.map +1 -1
  25. package/dist/codegen.go/src/core/options.js +3 -2
  26. package/dist/codegen.go/src/core/options.js.map +1 -1
  27. package/dist/codegen.go/src/core/polymorphics.d.ts.map +1 -1
  28. package/dist/codegen.go/src/core/polymorphics.js +55 -48
  29. package/dist/codegen.go/src/core/polymorphics.js.map +1 -1
  30. package/dist/codegen.go/src/core/responses.d.ts.map +1 -1
  31. package/dist/codegen.go/src/core/responses.js +28 -19
  32. package/dist/codegen.go/src/core/responses.js.map +1 -1
  33. package/dist/codegen.go/src/core/version.d.ts.map +1 -1
  34. package/dist/codegen.go/src/core/version.js +3 -2
  35. package/dist/codegen.go/src/core/version.js.map +1 -1
  36. package/dist/codegen.go/src/emitter.js +4 -1
  37. package/dist/codegen.go/src/emitter.js.map +1 -1
  38. package/dist/codegen.go/src/fake/factory.d.ts.map +1 -1
  39. package/dist/codegen.go/src/fake/factory.js +2 -2
  40. package/dist/codegen.go/src/fake/factory.js.map +1 -1
  41. package/dist/codegen.go/src/fake/servers.d.ts.map +1 -1
  42. package/dist/codegen.go/src/fake/servers.js +386 -259
  43. package/dist/codegen.go/src/fake/servers.js.map +1 -1
  44. package/dist/codemodel.go/src/client.d.ts +42 -5
  45. package/dist/codemodel.go/src/client.d.ts.map +1 -1
  46. package/dist/codemodel.go/src/client.js +13 -2
  47. package/dist/codemodel.go/src/client.js.map +1 -1
  48. package/dist/codemodel.go/src/param.d.ts +13 -2
  49. package/dist/codemodel.go/src/param.d.ts.map +1 -1
  50. package/dist/codemodel.go/src/param.js +6 -0
  51. package/dist/codemodel.go/src/param.js.map +1 -1
  52. package/dist/codemodel.go/src/type.d.ts +35 -12
  53. package/dist/codemodel.go/src/type.d.ts.map +1 -1
  54. package/dist/codemodel.go/src/type.js +14 -3
  55. package/dist/codemodel.go/src/type.js.map +1 -1
  56. package/dist/typespec-go/src/tcgcadapter/adapter.d.ts.map +1 -1
  57. package/dist/typespec-go/src/tcgcadapter/adapter.js +1 -2
  58. package/dist/typespec-go/src/tcgcadapter/adapter.js.map +1 -1
  59. package/dist/typespec-go/src/tcgcadapter/clients.d.ts +16 -1
  60. package/dist/typespec-go/src/tcgcadapter/clients.d.ts.map +1 -1
  61. package/dist/typespec-go/src/tcgcadapter/clients.js +205 -89
  62. package/dist/typespec-go/src/tcgcadapter/clients.js.map +1 -1
  63. package/dist/typespec-go/src/tcgcadapter/helpers.d.ts +22 -0
  64. package/dist/typespec-go/src/tcgcadapter/helpers.d.ts.map +1 -1
  65. package/dist/typespec-go/src/tcgcadapter/helpers.js +58 -0
  66. package/dist/typespec-go/src/tcgcadapter/helpers.js.map +1 -1
  67. package/dist/typespec-go/src/tcgcadapter/types.d.ts +23 -1
  68. package/dist/typespec-go/src/tcgcadapter/types.d.ts.map +1 -1
  69. package/dist/typespec-go/src/tcgcadapter/types.js +113 -26
  70. package/dist/typespec-go/src/tcgcadapter/types.js.map +1 -1
  71. package/package.json +11 -10
@@ -275,7 +275,7 @@ export class ClientAdapter {
275
275
  goClient.instance = constructable;
276
276
  // if no authentication type was specified, or the noAuth scheme was
277
277
  // explicitly specified, then include the WithNoCredential constructor
278
- if (authType === AuthTypes.Default || (authType & AuthTypes.NoAuth) === AuthTypes.NoAuth) {
278
+ if (authType === AuthTypes.Default || (authType & AuthTypes.NoAuth) !== 0) {
279
279
  goClient.instance.constructors.push(new go.Constructor(this.ta.getPkg(), `New${clientName}WithNoCredential`));
280
280
  }
281
281
  // propagate ctor params to all client ctors
@@ -383,7 +383,7 @@ export class ClientAdapter {
383
383
  adaptURIParam(sdkParam, forceRequired) {
384
384
  let paramType;
385
385
  if (sdkParam.isApiVersionParam) {
386
- paramType = new go.String();
386
+ paramType = this.ta.getStringType();
387
387
  }
388
388
  else {
389
389
  paramType = this.ta.getWireType(sdkParam.type, true, false);
@@ -429,7 +429,7 @@ export class ClientAdapter {
429
429
  }
430
430
  }
431
431
  const setLROInfo = function (goMethod, sdkMethod) {
432
- const lroOptions = hasDecorator('Azure.Core.@useFinalStateVia', sdkMethod.decorators);
432
+ const lroOptions = helpers.hasDecorator('@useFinalStateVia', sdkMethod.decorators);
433
433
  if (lroOptions) {
434
434
  goMethod.finalStateVia = lroOptions['finalState'];
435
435
  }
@@ -442,34 +442,26 @@ export class ClientAdapter {
442
442
  .join('.');
443
443
  }
444
444
  };
445
- const setPageableInfo = function (goMethod, sdkMethod) {
446
- if (sdkMethod.pagingMetadata.nextLinkVerb) {
447
- switch (sdkMethod.pagingMetadata.nextLinkVerb) {
448
- case 'GET':
449
- // we default to GET in the ctor for PageableMethod
450
- break;
451
- case 'POST':
452
- goMethod.nextLinkVerb = 'post';
453
- break;
454
- default:
455
- sdkMethod.pagingMetadata.nextLinkVerb;
456
- }
457
- }
458
- if (sdkMethod.pagingMetadata.nextLinkSegments) {
459
- goMethod.nextLinkName = capitalize(sdkMethod.pagingMetadata.nextLinkSegments
460
- .map((segment) => {
461
- if (segment.kind === 'property') {
462
- return ensureNameCase(segment.name);
463
- }
464
- else {
465
- throw new AdapterError('UnsupportedTsp', `unsupported next link segment kind ${segment.kind}`, sdkMethod.__raw?.node);
445
+ const setPageableInfo = (goMethod, sdkMethod) => {
446
+ return (paramsMap, respHeadersMap) => {
447
+ if (sdkMethod.pagingMetadata.nextLinkVerb) {
448
+ switch (sdkMethod.pagingMetadata.nextLinkVerb) {
449
+ case 'GET':
450
+ // we default to GET in the ctor for PageableMethod
451
+ break;
452
+ case 'POST':
453
+ goMethod.nextLinkVerb = 'post';
454
+ break;
455
+ default:
456
+ sdkMethod.pagingMetadata.nextLinkVerb;
466
457
  }
467
- })
468
- .join('.'));
469
- }
458
+ }
459
+ goMethod.strategy = this.adaptPagingStrategy(sdkMethod, paramsMap, respHeadersMap);
460
+ };
470
461
  };
471
462
  const statusCodes = getStatusCodes(sdkMethod.operation);
472
463
  let method;
464
+ let applyPageableInfo;
473
465
  switch (sdkMethod.kind) {
474
466
  case 'basic':
475
467
  method = new go.SyncMethod(methodName, goClient, sdkMethod.operation.path, sdkMethod.operation.verb, statusCodes, naming);
@@ -479,7 +471,7 @@ export class ClientAdapter {
479
471
  throw new AdapterError('UnsupportedTsp', `paging with re-injected parameters is not supported`, sdkMethod.__raw?.node);
480
472
  }
481
473
  method = new go.PageableMethod(methodName, goClient, sdkMethod.operation.path, sdkMethod.operation.verb, statusCodes, naming);
482
- setPageableInfo(method, sdkMethod);
474
+ applyPageableInfo = setPageableInfo(method, sdkMethod);
483
475
  break;
484
476
  case 'lro':
485
477
  method = new go.LROMethod(methodName, goClient, sdkMethod.operation.path, sdkMethod.operation.verb, statusCodes, naming);
@@ -488,7 +480,7 @@ export class ClientAdapter {
488
480
  case 'lropaging':
489
481
  method = new go.LROPageableMethod(methodName, goClient, sdkMethod.operation.path, sdkMethod.operation.verb, statusCodes, naming);
490
482
  setLROInfo(method, sdkMethod);
491
- setPageableInfo(method, sdkMethod);
483
+ applyPageableInfo = setPageableInfo(method, sdkMethod);
492
484
  break;
493
485
  default:
494
486
  sdkMethod;
@@ -497,7 +489,79 @@ export class ClientAdapter {
497
489
  method.docs.summary = sdkMethod.summary;
498
490
  method.docs.description = sdkMethod.doc;
499
491
  goClient.methods.push(method);
500
- this.populateMethod(sdkMethod, method);
492
+ const pageableInfo = this.populateMethod(sdkMethod, method);
493
+ // NOTE: we can't apply pageable info until the method has been populated
494
+ applyPageableInfo?.(pageableInfo.params, pageableInfo.respHeaders);
495
+ }
496
+ /**
497
+ * creates the pageable strategy based on the method definition.
498
+ * returns undefined if no strategy is required.
499
+ *
500
+ * @param sdkMethod the tcgc pageable method for which to create a strategy
501
+ * @returns the pageable strategy or undefined
502
+ */
503
+ adaptPagingStrategy(sdkMethod, paramsMap, respHeadersMap) {
504
+ const buildNextLinkPath = (segments) => {
505
+ // build the field path for the next link segments
506
+ const nextLinkPath = new Array();
507
+ for (const segment of segments) {
508
+ if (segment.kind !== 'property') {
509
+ throw new AdapterError('InternalError', `unexpected kind ${segment.kind} for next link segment in operation ${sdkMethod.name}`, sdkMethod.__raw?.node);
510
+ }
511
+ const nextLinkField = this.ta.fieldsMap.get(segment);
512
+ if (!nextLinkField) {
513
+ // the most likely explanation for this is lack of reference equality
514
+ throw new AdapterError('InternalError', `missing next link field name ${segment.name} for operation ${sdkMethod.name}`, sdkMethod.__raw?.node);
515
+ }
516
+ nextLinkPath.push(nextLinkField);
517
+ }
518
+ return nextLinkPath;
519
+ };
520
+ if (sdkMethod.pagingMetadata.nextLinkOperation) {
521
+ throw new AdapterError('UnsupportedTsp', 'next page operation NYI', sdkMethod.__raw?.node);
522
+ }
523
+ else if (sdkMethod.pagingMetadata.nextLinkSegments) {
524
+ return new go.PageableStrategyNextLink(buildNextLinkPath(sdkMethod.pagingMetadata.nextLinkSegments));
525
+ }
526
+ else if (sdkMethod.pagingMetadata.continuationTokenParameterSegments && sdkMethod.pagingMetadata.continuationTokenResponseSegments) {
527
+ const tokenReq = sdkMethod.pagingMetadata.continuationTokenParameterSegments[0];
528
+ const tokenResp = sdkMethod.pagingMetadata.continuationTokenResponseSegments[0];
529
+ // find the continuation token parameter
530
+ let requestToken;
531
+ switch (tokenReq.kind) {
532
+ case 'method': {
533
+ const tokenParam = paramsMap.get(tokenReq);
534
+ if (!tokenParam) {
535
+ throw new AdapterError('InternalError', `missing continuation token request parameter name ${tokenReq.name} for operation ${sdkMethod.name}`, sdkMethod.__raw?.node);
536
+ }
537
+ requestToken = tokenParam;
538
+ break;
539
+ }
540
+ default:
541
+ throw new AdapterError('InternalError', `unhandled continuationTokenParameterSegment kind ${tokenReq.kind}`, tokenReq.__raw?.node);
542
+ }
543
+ // find the continuation token response
544
+ let responseToken;
545
+ switch (tokenResp.kind) {
546
+ case 'property': {
547
+ responseToken = new go.PageableStrategyNextLink(buildNextLinkPath(sdkMethod.pagingMetadata.continuationTokenResponseSegments));
548
+ break;
549
+ }
550
+ case 'responseheader': {
551
+ const tokenHeader = respHeadersMap.get(tokenResp);
552
+ if (!tokenHeader) {
553
+ throw new AdapterError('InternalError', `missing continuation token response header name ${tokenResp.name} for operation ${sdkMethod.name}`, sdkMethod.__raw?.node);
554
+ }
555
+ responseToken = tokenHeader;
556
+ break;
557
+ }
558
+ default:
559
+ throw new AdapterError('InternalError', `missing continuation token`, sdkMethod.__raw?.node);
560
+ }
561
+ return new go.PageableStrategyContinuationToken(requestToken, responseToken);
562
+ }
563
+ // operation is pageable but doesn't yet support fetching subsequent pages
564
+ return undefined;
501
565
  }
502
566
  populateMethod(sdkMethod, method) {
503
567
  if (method.kind === 'nextPageMethod') {
@@ -525,25 +589,22 @@ export class ClientAdapter {
525
589
  }
526
590
  method.optionalParamsGroup = new go.ParameterGroup(this.ta.getPkg(), optsGroupName, optionalParamsGroupName, false, 'method');
527
591
  method.optionalParamsGroup.docs.summary = createOptionsTypeDescription(optionalParamsGroupName, this.getMethodNameForDocComment(method));
528
- method.returns = this.adaptResponseEnvelope(sdkMethod, method);
529
- // find the api version param to use for the doc comment.
530
- // we can't use sdkMethod.apiVersions as that includes all
531
- // of the api versions supported by the service.
532
- for (const opParam of sdkMethod.operation.parameters) {
533
- if (opParam.isApiVersionParam && opParam.clientDefaultValue) {
534
- method.apiVersions.push(opParam.clientDefaultValue);
535
- break;
536
- }
537
- }
592
+ const respInfo = this.adaptResponseEnvelope(sdkMethod, method);
593
+ method.returns = respInfo.respEnv;
538
594
  const paramMapping = this.adaptMethodParameters(sdkMethod, method);
539
595
  // we must do this after adapting method params as it can add optional params
540
596
  this.ta.getPkg().paramGroups.push(this.adaptParameterGroup(method.optionalParamsGroup));
541
597
  if (this.ta.codeModel.options.generateExamples) {
542
- this.adaptHttpOperationExamples(sdkMethod, method, paramMapping);
598
+ this.adaptHttpOperationExamples(sdkMethod, method, paramMapping.exampleParams);
543
599
  }
600
+ return {
601
+ params: paramMapping.paramsMap,
602
+ respHeaders: respInfo.respHeaders,
603
+ };
544
604
  }
545
605
  adaptMethodParameters(sdkMethod, method) {
546
606
  const paramMapping = new Map();
607
+ const pageableParamsMap = new Map();
547
608
  let optionalGroup;
548
609
  if (method.kind !== 'nextPageMethod') {
549
610
  // NextPageMethods don't have optional params
@@ -637,10 +698,11 @@ export class ClientAdapter {
637
698
  }
638
699
  case 'binary':
639
700
  if (opParam.defaultContentType.match(/multipart/i)) {
640
- adaptedParam = new go.MultipartFormBodyParameter(paramName, this.ta.getReadSeekCloser(false), paramStyle, byVal);
701
+ adaptedParam = this.adaptMultipartFormParameter(param, paramStyle, byVal);
641
702
  }
642
703
  else {
643
- adaptedParam = new go.BodyParameter(paramName, contentType, `"${opParam.defaultContentType}"`, this.ta.getReadSeekCloser(false), paramStyle, byVal);
704
+ const contentTypeLiteral = this.ta.getLiteral(this.ta.getStringType(), opParam.defaultContentType);
705
+ adaptedParam = new go.BodyParameter(paramName, contentType, contentTypeLiteral, this.ta.getReadSeekCloser(false), paramStyle, byVal);
644
706
  }
645
707
  break;
646
708
  default:
@@ -667,7 +729,7 @@ export class ClientAdapter {
667
729
  }
668
730
  if (correspondingOpParams.length === 0) {
669
731
  // No properties mapped to HTTP params, treat as regular parameter
670
- adaptedParam = this.adaptMethodParameter(opParam, method.httpMethod);
732
+ adaptedParam = this.adaptMethodParameter(method, opParam);
671
733
  }
672
734
  else {
673
735
  // Parameter group handling:
@@ -687,7 +749,7 @@ export class ClientAdapter {
687
749
  for (let i = 0; i < modelProperties.length; i++) {
688
750
  const property = modelProperties[i];
689
751
  const propertyOpParam = correspondingOpParams[i];
690
- const adaptedPropertyParam = this.adaptMethodParameter(propertyOpParam, method.httpMethod);
752
+ const adaptedPropertyParam = this.adaptMethodParameter(method, propertyOpParam);
691
753
  adaptedPropertyParam.docs.summary = property.summary;
692
754
  adaptedPropertyParam.docs.description = property.doc;
693
755
  if (adaptedPropertyParam.style === 'required' || adaptedPropertyParam.style === 'literal') {
@@ -730,10 +792,20 @@ export class ClientAdapter {
730
792
  }
731
793
  }
732
794
  else {
733
- adaptedParam = this.adaptMethodParameter(opParam, method.httpMethod);
795
+ adaptedParam = this.adaptMethodParameter(method, opParam);
796
+ if (method.kind !== 'nextPageMethod' && go.isPageableMethod(method)) {
797
+ switch (adaptedParam.kind) {
798
+ case 'headerScalarParam':
799
+ case 'queryScalarParam':
800
+ pageableParamsMap.set(param, adaptedParam);
801
+ }
802
+ }
734
803
  }
735
804
  adaptedParam.docs.summary = param.summary;
736
805
  adaptedParam.docs.description = param.doc;
806
+ if (go.isClientSideDefault(adaptedParam.style) && !adaptedParam.docs.summary && !adaptedParam.docs.description) {
807
+ adaptedParam.docs.summary = helpers.getClientDefaultValueDoc(adaptedParam.style.defaultValue);
808
+ }
737
809
  addParameterToMethod(adaptedParam, opParam);
738
810
  if (adaptedParam.style !== 'required' && adaptedParam.style !== 'literal') {
739
811
  // add optional method param to the options param group
@@ -748,7 +820,7 @@ export class ClientAdapter {
748
820
  // look for them in the operation parameters.
749
821
  for (const opParam of allOpParams) {
750
822
  if (opParam.onClient) {
751
- const adaptedParam = this.adaptMethodParameter(opParam, method.httpMethod);
823
+ const adaptedParam = this.adaptMethodParameter(method, opParam);
752
824
  adaptedParam.docs.summary = opParam.summary;
753
825
  adaptedParam.docs.description = opParam.doc;
754
826
  method.parameters.unshift(adaptedParam);
@@ -783,7 +855,10 @@ export class ClientAdapter {
783
855
  }
784
856
  }
785
857
  }
786
- return paramMapping;
858
+ return {
859
+ exampleParams: paramMapping,
860
+ paramsMap: pageableParamsMap,
861
+ };
787
862
  }
788
863
  adaptContentType(contentTypeStr) {
789
864
  // we only recognize/support JSON, text, and XML content types, so assume anything else is binary
@@ -803,16 +878,30 @@ export class ClientAdapter {
803
878
  /**
804
879
  * adapts the provided operation parameter to a Go method parameter
805
880
  *
881
+ * @param method the method to which the parameter belongs
806
882
  * @param opParam the operation parameter to adapt
807
- * @param verb the HTTP verb used for the operation to which the parameter belongs
808
883
  * @returns the adapted Go method parameter
809
884
  */
810
- adaptMethodParameter(opParam, verb) {
885
+ adaptMethodParameter(method, opParam) {
811
886
  if (opParam.isApiVersionParam) {
812
887
  // we emit the api version param inline as a literal, never as a param.
813
888
  // the ClientOptions.APIVersion setting is used to change the version.
814
- const paramType = opParam.clientDefaultValue ? new go.Literal(new go.String(), opParam.clientDefaultValue) : new go.String();
815
- const paramStyle = opParam.clientDefaultValue ? 'literal' : opParam.optional ? 'optional' : 'required';
889
+ let paramType;
890
+ let paramStyle;
891
+ if (opParam.clientDefaultValue) {
892
+ const client = method.receiver.type;
893
+ if (!client.apiVersion) {
894
+ // first method for this client, so apiVersion hasn't been set yet
895
+ const literalValue = new go.Literal(this.ta.getStringType(), opParam.clientDefaultValue);
896
+ client.apiVersion = new go.ConstantDef(`default${client.name}Version`, literalValue);
897
+ }
898
+ paramType = new go.Literal(client.apiVersion, client.apiVersion.name);
899
+ paramStyle = 'literal';
900
+ }
901
+ else {
902
+ paramType = this.ta.getStringType();
903
+ paramStyle = opParam.optional ? 'optional' : 'required';
904
+ }
816
905
  const paramLoc = opParam.onClient ? 'client' : 'method';
817
906
  let apiVersionParam;
818
907
  switch (opParam.kind) {
@@ -862,7 +951,7 @@ export class ClientAdapter {
862
951
  if (opParam.kind === 'body') {
863
952
  const contentType = this.adaptContentType(opParam.defaultContentType);
864
953
  // only force modeled body params to be required (binary payloads can be optional)
865
- if (contentType !== 'binary' && (verb === 'patch' || verb === 'put')) {
954
+ if (contentType !== 'binary' && (method.httpMethod === 'patch' || method.httpMethod === 'put')) {
866
955
  paramStyle = 'required';
867
956
  }
868
957
  }
@@ -873,7 +962,7 @@ export class ClientAdapter {
873
962
  case 'body':
874
963
  // TODO: form data? (non-multipart)
875
964
  if (opParam.defaultContentType.match(/multipart/i)) {
876
- adaptedParam = new go.MultipartFormBodyParameter(paramName, this.ta.getWireType(methodParam.type, false, true), paramStyle, byVal);
965
+ adaptedParam = this.adaptMultipartFormParameter(methodParam, paramStyle, byVal);
877
966
  }
878
967
  else {
879
968
  const contentType = this.adaptContentType(opParam.defaultContentType);
@@ -882,7 +971,8 @@ export class ClientAdapter {
882
971
  // tcgc models binary params as 'bytes' but we want an io.ReadSeekCloser
883
972
  bodyType = this.ta.getReadSeekCloser(methodParam.type.kind === 'array');
884
973
  }
885
- adaptedParam = new go.BodyParameter(paramName, contentType, `"${opParam.defaultContentType}"`, bodyType, paramStyle, byVal);
974
+ const contentTypeLiteral = this.ta.getLiteral(this.ta.getStringType(), opParam.defaultContentType);
975
+ adaptedParam = new go.BodyParameter(paramName, contentType, contentTypeLiteral, bodyType, paramStyle, byVal);
886
976
  if (contentType === 'XML' && methodParam.type.kind === 'array') {
887
977
  // this is for compat with autorest.go
888
978
  adaptedParam.xml = new go.XMLInfo();
@@ -940,6 +1030,46 @@ export class ClientAdapter {
940
1030
  }
941
1031
  return adaptedParam;
942
1032
  }
1033
+ /**
1034
+ * adapts a multipart form body parameter from its tcgc representation.
1035
+ * for generated wrapper types (isGeneratedName), unwraps to the inner property.
1036
+ * for file parts with a fixed content type (e.g. HttpPart<File<"image/png">>),
1037
+ * uses a MultipartContent type with the content type baked in.
1038
+ */
1039
+ adaptMultipartFormParameter(param, paramStyle, byVal) {
1040
+ let paramName = param.name;
1041
+ if (param.type.kind !== 'model') {
1042
+ throw new AdapterError('InternalError', `unexpected kind ${param.type.kind}`, param.__raw?.node);
1043
+ }
1044
+ let paramType = param.type;
1045
+ let multipartOptions;
1046
+ if (paramType.isGeneratedName) {
1047
+ // tcgc wraps inline multipart params in a generated model with a single property.
1048
+ // unwrap to the inner property to get the actual param name and type.
1049
+ if (paramType.properties.length !== 1) {
1050
+ throw new AdapterError('InternalError', `unexpected number of properties: ${paramType.properties.length}`, paramType.__raw?.node);
1051
+ }
1052
+ const prop = paramType.properties[0];
1053
+ paramName = prop.name;
1054
+ multipartOptions = prop.serializationOptions.multipart;
1055
+ paramType = prop.type;
1056
+ }
1057
+ let type;
1058
+ // only use MultipartContent for file parts with a fixed content type.
1059
+ // non-file parts (e.g. HttpPart<{ @body body: float64; @header contentType: "text/plain" }>)
1060
+ // should retain their underlying type (e.g. float64).
1061
+ if (multipartOptions?.isFilePart && multipartOptions.contentType?.type.kind === 'constant' && multipartOptions.defaultContentTypes.length === 1) {
1062
+ type = this.ta.getMultipartContent(paramType.kind === 'array', multipartOptions.defaultContentTypes[0]);
1063
+ }
1064
+ else if (paramType.kind === 'bytes' && paramType.encode === 'bytes') {
1065
+ type = this.ta.getReadSeekCloser(false);
1066
+ }
1067
+ else {
1068
+ type = this.ta.getWireType(paramType, true, true);
1069
+ }
1070
+ paramName = getEscapedReservedName(ensureNameCase(paramName, paramStyle === 'required'), 'Param');
1071
+ return new go.MultipartFormBodyParameter(paramName, type, paramStyle, byVal);
1072
+ }
943
1073
  getMethodNameForDocComment(method) {
944
1074
  let methodName;
945
1075
  switch (method.kind) {
@@ -972,6 +1102,7 @@ export class ClientAdapter {
972
1102
  }
973
1103
  const respEnv = new go.ResponseEnvelope(respEnvName, { summary: createResponseEnvelopeDescription(respEnvName, this.getMethodNameForDocComment(method)) }, method);
974
1104
  this.ta.getPkg().responseEnvelopes.push(respEnv);
1105
+ const pageableRespHeadersMap = new Map();
975
1106
  // add any headers
976
1107
  const addedHeaders = new Set();
977
1108
  if (!go.isLROMethod(method)) {
@@ -990,6 +1121,9 @@ export class ClientAdapter {
990
1121
  }
991
1122
  else {
992
1123
  headerResp = new go.HeaderScalarResponse(ensureNameCase(httpHeader.name), this.adaptHeaderScalarType(httpHeader.type, false), httpHeader.serializedName, helpers.isTypePassedByValue(httpHeader.type));
1124
+ if (go.isPageableMethod(method)) {
1125
+ pageableRespHeadersMap.set(httpHeader, headerResp);
1126
+ }
993
1127
  }
994
1128
  headerResp.docs.summary = httpHeader.summary;
995
1129
  headerResp.docs.description = httpHeader.doc;
@@ -1006,7 +1140,10 @@ export class ClientAdapter {
1006
1140
  }
1007
1141
  if (!sdkResponseType) {
1008
1142
  // method doesn't return a type, so we're done
1009
- return respEnv;
1143
+ return {
1144
+ respEnv: respEnv,
1145
+ respHeaders: pageableRespHeadersMap,
1146
+ };
1010
1147
  }
1011
1148
  if (sdkResponseType.kind === 'nullable') {
1012
1149
  // unwrap the nullable type, this will only happen for operations with two responses and one of them does not have a body
@@ -1057,7 +1194,10 @@ export class ClientAdapter {
1057
1194
  if (contentType === 'binary') {
1058
1195
  respEnv.result = new go.BinaryResult('Body');
1059
1196
  respEnv.result.docs.summary = 'Body contains the streaming response.';
1060
- return respEnv;
1197
+ return {
1198
+ respEnv: respEnv,
1199
+ respHeaders: pageableRespHeadersMap,
1200
+ };
1061
1201
  }
1062
1202
  else if (sdkResponseType.kind === 'model') {
1063
1203
  let modelType;
@@ -1141,7 +1281,10 @@ export class ClientAdapter {
1141
1281
  throw new AdapterError('InternalError', `invalid monomorphic result type ${resultType.kind}`, sdkResponseType.__raw?.node);
1142
1282
  }
1143
1283
  }
1144
- return respEnv;
1284
+ return {
1285
+ respEnv: respEnv,
1286
+ respHeaders: pageableRespHeadersMap,
1287
+ };
1145
1288
  }
1146
1289
  /**
1147
1290
  * creates the monomorphic response field name based on its type.
@@ -1263,7 +1406,7 @@ export class ClientAdapter {
1263
1406
  if (param.isApiVersionParam) {
1264
1407
  // we force the API version param type to a string
1265
1408
  // so it matches the ClientOptions.APIVersion type
1266
- adaptedType = new go.String();
1409
+ adaptedType = this.ta.getStringType();
1267
1410
  }
1268
1411
  else {
1269
1412
  const adaptedWireType = this.ta.getWireType(param.type, false, false);
@@ -1272,17 +1415,7 @@ export class ClientAdapter {
1272
1415
  }
1273
1416
  adaptedType = adaptedWireType;
1274
1417
  }
1275
- if (adaptedType.kind === 'constant') {
1276
- // find the matching constant for the clientDefaultValue
1277
- for (const constValue of adaptedType.values) {
1278
- if (constValue.value === param.clientDefaultValue) {
1279
- return new go.ClientSideDefault(new go.Literal(adaptedType, constValue));
1280
- }
1281
- }
1282
- throw new AdapterError('InternalError', `didn't find clientDefaultValue constant with value ${param.clientDefaultValue} for parameter`, param.__raw?.node);
1283
- }
1284
- // non-constant clientDefaultValue
1285
- return new go.ClientSideDefault(new go.Literal(adaptedType, param.clientDefaultValue));
1418
+ return new go.ClientSideDefault(this.ta.getLiteral(adaptedType, param.clientDefaultValue, helpers.isExtensibleEnum(param.type)));
1286
1419
  }
1287
1420
  else if (param.optional) {
1288
1421
  return 'optional';
@@ -1447,9 +1580,8 @@ export class ClientAdapter {
1447
1580
  if (goType.kind === 'interface' || goType.kind === 'model' || goType.kind === 'polymorphicModel') {
1448
1581
  let concreteType;
1449
1582
  if (goType.kind === 'interface') {
1450
- concreteType = goType.possibleTypes.find(
1451
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1452
- (t) => t.discriminatorValue?.literal === exampleType.type.discriminatorValue || t.discriminatorValue?.literal.value === exampleType.type.discriminatorValue);
1583
+ concreteType = goType.possibleTypes.find((t) => t.discriminatorValue?.literal === exampleType.type.discriminatorValue ||
1584
+ (t.discriminatorValue?.literal).value === exampleType.type.discriminatorValue);
1453
1585
  if (concreteType === undefined) {
1454
1586
  // can't find the sub type of a discriminated type, fallback to the base type
1455
1587
  concreteType = goType.rootType;
@@ -1491,22 +1623,6 @@ export class ClientAdapter {
1491
1623
  throw new AdapterError('InternalError', `can not map go type into example type ${exampleType.kind}`);
1492
1624
  }
1493
1625
  }
1494
- /**
1495
- * returns the record for the specified decorator's arguments if it exists
1496
- *
1497
- * @param name the name of the decorator to find
1498
- * @param decorators the array of decorators to search
1499
- * @returns the decorator's record of arguments or undefined
1500
- */
1501
- /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
1502
- function hasDecorator(name, decorators) {
1503
- for (const decorator of decorators) {
1504
- if (decorator.name === name) {
1505
- return decorator.arguments;
1506
- }
1507
- }
1508
- return undefined;
1509
- }
1510
1626
  function isHttpStatusCodeRange(statusCode) {
1511
1627
  return statusCode.start !== undefined;
1512
1628
  }