@azure-tools/typespec-go 0.16.0-dev.17 → 0.16.0-dev.19

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 (34) hide show
  1. package/dist/src/codegen/core/example.d.ts.map +1 -1
  2. package/dist/src/codegen/core/example.js +4 -5
  3. package/dist/src/codegen/core/example.js.map +1 -1
  4. package/dist/src/codegen/core/helpers.d.ts +13 -3
  5. package/dist/src/codegen/core/helpers.d.ts.map +1 -1
  6. package/dist/src/codegen/core/helpers.js +50 -14
  7. package/dist/src/codegen/core/helpers.js.map +1 -1
  8. package/dist/src/codegen/core/index.d.ts +17 -0
  9. package/dist/src/codegen/core/index.d.ts.map +1 -0
  10. package/dist/src/codegen/core/index.js +21 -0
  11. package/dist/src/codegen/core/index.js.map +1 -0
  12. package/dist/src/codegen/core/operations.d.ts +0 -1
  13. package/dist/src/codegen/core/operations.d.ts.map +1 -1
  14. package/dist/src/codegen/core/operations.js +60 -1127
  15. package/dist/src/codegen/core/operations.js.map +1 -1
  16. package/dist/src/codegen/core/request-handler.d.ts +14 -0
  17. package/dist/src/codegen/core/request-handler.d.ts.map +1 -0
  18. package/dist/src/codegen/core/request-handler.js +746 -0
  19. package/dist/src/codegen/core/request-handler.js.map +1 -0
  20. package/dist/src/codegen/core/response-handler.d.ts +12 -0
  21. package/dist/src/codegen/core/response-handler.d.ts.map +1 -0
  22. package/dist/src/codegen/core/response-handler.js +288 -0
  23. package/dist/src/codegen/core/response-handler.js.map +1 -0
  24. package/dist/src/codegen/emitter.d.ts.map +1 -1
  25. package/dist/src/codegen/emitter.js +21 -37
  26. package/dist/src/codegen/emitter.js.map +1 -1
  27. package/dist/src/codegen/fake/index.d.ts +3 -0
  28. package/dist/src/codegen/fake/index.d.ts.map +1 -0
  29. package/dist/src/codegen/fake/index.js +7 -0
  30. package/dist/src/codegen/fake/index.js.map +1 -0
  31. package/dist/src/codegen/fake/servers.d.ts.map +1 -1
  32. package/dist/src/codegen/fake/servers.js +12 -13
  33. package/dist/src/codegen/fake/servers.js.map +1 -1
  34. package/package.json +15 -15
@@ -7,6 +7,8 @@ import * as naming from "../../naming/naming.js";
7
7
  import { CodegenError } from "./errors.js";
8
8
  import * as helpers from "./helpers.js";
9
9
  import { ImportManager } from "./imports.js";
10
+ import { createRequestHandler } from "./request-handler.js";
11
+ import { createResponseHandler } from "./response-handler.js";
10
12
  // represents the generated content for an operation group
11
13
  export class OperationGroupContent {
12
14
  name;
@@ -160,10 +162,11 @@ export function generateOperations(pkg, target, options) {
160
162
  opText += generateLROBeginMethod(method, options, imports, indent);
161
163
  }
162
164
  opText += generateOperation(method, options, imports, indent);
163
- opText += createProtocolRequest(azureARM, method, imports, indent);
164
- if (method.kind !== "lroMethod") {
165
- // LRO responses are handled elsewhere, with the exception of pageable LROs
166
- opText += createProtocolResponse(method, imports, indent);
165
+ opText += createRequestHandler(azureARM, method, imports, indent);
166
+ if (needsResponseHandler(method) && method.kind !== "lroMethod") {
167
+ // we don't emit the response handler for vanilla LROs as the Poller[T]
168
+ // handles that. we do need it for pageable LROs though.
169
+ opText += createResponseHandler(method, imports, indent);
167
170
  }
168
171
  if (go.isPageableMethod(method) &&
169
172
  method.strategy?.kind === "nextLink" &&
@@ -174,7 +177,7 @@ export function generateOperations(pkg, target, options) {
174
177
  }
175
178
  }
176
179
  for (const method of nextPageMethods) {
177
- opText += createProtocolRequest(azureARM, method, imports, indent);
180
+ opText += createRequestHandler(azureARM, method, imports, indent);
178
181
  }
179
182
  // stitch it all together
180
183
  let text = helpers.contentPreamble(pkg);
@@ -434,136 +437,20 @@ function generateConstructors(client, type, imports, indent) {
434
437
  }
435
438
  return ctorText;
436
439
  }
437
- // use this to generate the code that will help process values returned in response headers
438
- function formatHeaderResponseValue(method, headerResp, respObj, zeroResp, imports, indent) {
439
- // dictionaries are handled slightly different so we do that first
440
- if (headerResp.kind === "headerMapResponse") {
441
- imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/to");
442
- imports.add("strings");
443
- const headerPrefix = headerResp.headerName;
444
- let text = `${indent.get()}for hh := range resp.Header {\n`;
445
- text += `${indent.push().get()}if len(hh) > len("${headerPrefix}") && strings.EqualFold(hh[:len("${headerPrefix}")], "${headerPrefix}") {\n`;
446
- text += `${indent.push().get()}if ${respObj}.${headerResp.fieldName} == nil {\n`;
447
- text += `${indent.push().get()}${respObj}.${headerResp.fieldName} = map[string]*string{}\n`;
448
- text += `${indent.pop().get()}}\n`;
449
- text += `${indent.get()}${respObj}.${headerResp.fieldName}[hh[len("${headerPrefix}"):]] = to.Ptr(resp.Header.Get(hh))\n`;
450
- text += `${indent.pop().get()}}\n`;
451
- text += `${indent.pop().get()}}\n`;
452
- return text;
453
- }
454
- let text = `${indent.get()}if val := resp.Header.Get("${helpers.canonicalizeHeaderName(headerResp.headerName)}"); val != "" {\n`;
455
- indent.push();
456
- let name = naming.uncapitalize(headerResp.fieldName);
457
- let byRef = "&";
458
- switch (headerResp.type.kind) {
459
- case "constant":
460
- case "etag":
461
- text += `${indent.get()}${respObj}.${headerResp.fieldName} = (*${go.getTypeDeclaration(headerResp.type, method.receiver.type.pkg)})(&val)\n`;
462
- indent.pop();
463
- text += `${indent.get()}}\n`;
464
- return text;
465
- case "encodedBytes":
466
- // a base-64 encoded value in string format
467
- imports.add("encoding/base64");
468
- text += `${indent.get()}${name}, err := base64.${helpers.formatBytesEncoding(headerResp.type.encoding)}Encoding.DecodeString(val)\n`;
469
- byRef = "";
470
- break;
471
- case "literal":
472
- text += `${indent.get()}${respObj}.${headerResp.fieldName} = &val\n`;
473
- indent.pop();
474
- text += `${indent.get()}}\n`;
475
- return text;
476
- case "scalar":
477
- text += emitScalarParsing(headerResp.type, "val", name, imports, indent);
478
- break;
479
- case "string":
480
- text += `${indent.get()}${respObj}.${headerResp.fieldName} = &val\n`;
481
- text += `${indent.pop().get()}}\n`;
482
- return text;
483
- case "time":
484
- imports.add("time");
485
- switch (headerResp.type.format) {
486
- case "RFC1123":
487
- case "RFC3339":
488
- case "RFC7231":
489
- text += `${indent.get()}${name}, err := time.Parse(${headerResp.type.format === "RFC3339" ? helpers.RFC3339Format : helpers.RFC1123Format}, val)\n`;
490
- break;
491
- case "PlainDate":
492
- text += `${indent.get()}${name}, err := time.Parse(${helpers.plainDateFormat}, val)\n`;
493
- break;
494
- case "PlainTime":
495
- text += `${indent.get()}${name}, err := time.Parse(${helpers.plainTimeFormat}, val)\n`;
496
- break;
497
- case "Unix":
498
- imports.add("strconv");
499
- imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/to");
500
- text += `${indent.get()}sec, err := strconv.ParseInt(val, 10, 64)\n`;
501
- name = "to.Ptr(time.Unix(sec, 0))";
502
- byRef = "";
503
- break;
504
- default:
505
- headerResp.type.format;
506
- }
507
- }
508
- // NOTE: only cases that required parsing will fall through to here
509
- text += `${indent.get()}if err != nil {\n`;
510
- text += `${indent.push().get()}return ${zeroResp}, err\n`;
511
- text += `${indent.pop().get()}}\n`;
512
- text += `${indent.get()}${respObj}.${headerResp.fieldName} = ${byRef}${name}\n`;
513
- text += `${indent.pop().get()}}\n`;
514
- return text;
515
- }
516
- /**
517
- * emits the code for parsing scalar types from a string.
518
- * note that the parsing error result is placed into a
519
- * local var named "err".
520
- *
521
- * @param scalar the type of scalar to parse
522
- * @param src the source var that contains the scalar in string format
523
- * @param dst the destination var that contains the result
524
- * @param imports the import manager currently in scope
525
- * @param indent the indentation helper currently in scope
526
- * @returns the scalar parsing code
527
- */
528
- function emitScalarParsing(scalar, src, dst, imports, indent) {
529
- imports.add("strconv");
530
- switch (scalar.type) {
531
- case "bool":
532
- return `${indent.get()}${dst}, err := strconv.ParseBool(${src})\n`;
533
- case "float32":
534
- return (`${indent.get()}${dst}32, err := strconv.ParseFloat(${src}, 32)\n` +
535
- `${indent.get()}${dst} := float32(${dst}32)\n`);
536
- case "float64":
537
- return `${indent.get()}${dst}, err := strconv.ParseFloat(${src}, 64)\n`;
538
- case "int32":
539
- return (`${indent.get()}${dst}32, err := strconv.ParseInt(${src}, 10, 32)\n` +
540
- `${indent.get()}${dst} := int32(${dst}32)\n`);
541
- case "int64":
542
- return `${indent.get()}${dst}, err := strconv.ParseInt(${src}, 10, 64)\n`;
543
- default:
544
- throw new CodegenError("InternalError", `unhandled scalar type ${scalar.type}`);
545
- }
546
- }
547
440
  /**
548
441
  * returns the zero value for the specified method.
549
442
  * note that the zero value will be different depending
550
443
  * on which API for the method is being called.
551
444
  *
552
445
  * @param method the method to determine the zero value
553
- * @param apiType the method's API that's being invoked
554
- * lro - the exported LRO API
555
- * op - the operation method. for sync methods this is the exported API. for LROs it's the internal method called by Begin*
556
- * handler - the internal response handler method
557
446
  * @returns the zero value
558
447
  */
559
- function getZeroReturnValue(method, apiType) {
448
+ function getZeroReturnValue(method) {
560
449
  let returnType = `${method.returns.name}{}`;
561
450
  if (go.isLROMethod(method)) {
562
- if (apiType === "lro" || apiType === "op") {
563
- // the api returns a *Poller[T]
564
- // the operation returns an *http.Response
565
- returnType = "nil";
566
- }
451
+ // the api returns a *Poller[T]
452
+ // the operation returns an *http.Response
453
+ returnType = "nil";
567
454
  }
568
455
  return returnType;
569
456
  }
@@ -641,17 +528,8 @@ function emitPagerDefinition(method, options, imports, indent) {
641
528
  indent.push();
642
529
  const reqParams = helpers.getCreateRequestParameters(method);
643
530
  if (options.generateFakes) {
644
- text += `${indent.get()}ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "${method.receiver.type.name}.${fixUpMethodName(method)}")\n`;
531
+ text += `${indent.get()}ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "${method.receiver.type.name}.${helpers.fixUpMethodName(method)}")\n`;
645
532
  }
646
- /** emits code to check the HTTP status code and conditionally call the response handler */
647
- const emitStatusCodeCheckAndResponse = function (respVarName, indent) {
648
- let content = `${indent.get()}${helpers.buildIfBlock(indent, {
649
- condition: `!runtime.HasStatusCode(${respVarName}, http.StatusOK)`,
650
- body: (indent) => `${indent.get()}return ${getZeroReturnValue(method, "op")}, runtime.NewResponseError(${respVarName})\n`,
651
- })}\n`;
652
- content += `${indent.get()}return client.${method.naming.responseMethod}(${respVarName})\n`;
653
- return content;
654
- };
655
533
  if (method.strategy) {
656
534
  switch (method.strategy.kind) {
657
535
  case "continuationToken": {
@@ -683,7 +561,7 @@ function emitPagerDefinition(method, options, imports, indent) {
683
561
  })}\n`;
684
562
  text += callCreateRequestWithErrCheck(method, "req", indent, `&${optionsCopy}`);
685
563
  text += callPipelineDoWithErrCheck(method, "req", "resp", indent);
686
- text += emitStatusCodeCheckAndResponse("resp", indent);
564
+ text += `${indent.get()}return client.${method.naming.responseMethod}(resp, ${helpers.formatStatusCodes(method.httpStatusCodes)})\n`;
687
565
  break;
688
566
  }
689
567
  case "nextLink": {
@@ -737,7 +615,7 @@ function emitPagerDefinition(method, options, imports, indent) {
737
615
  text += `${indent.get()}if err != nil {\n`;
738
616
  text += `${indent.push().get()}return ${method.returns.name}{}, err\n`;
739
617
  text += `${indent.pop().get()}}\n`;
740
- text += `${indent.get()}return client.${method.naming.responseMethod}(resp)\n`;
618
+ text += `${indent.get()}return client.${method.naming.responseMethod}(resp, ${helpers.formatStatusCodes(method.httpStatusCodes)})\n`;
741
619
  }
742
620
  }
743
621
  }
@@ -745,7 +623,7 @@ function emitPagerDefinition(method, options, imports, indent) {
745
623
  // this is the singular page case, no fetcher helper required
746
624
  text += callCreateRequestWithErrCheck(method, "req", indent);
747
625
  text += callPipelineDoWithErrCheck(method, "req", "resp", indent);
748
- text += emitStatusCodeCheckAndResponse("resp", indent);
626
+ text += `${indent.get()}return client.${method.naming.responseMethod}(resp, ${helpers.formatStatusCodes(method.httpStatusCodes)})\n`;
749
627
  }
750
628
  text += `${indent.pop().get()}},\n`; // end Fetcher func
751
629
  if (options.injectSpans) {
@@ -767,7 +645,7 @@ function emitPagerDefinition(method, options, imports, indent) {
767
645
  function callCreateRequestWithErrCheck(method, reqVarName, indent, optionsParam) {
768
646
  const reqParams = helpers.getCreateRequestParameters(method, optionsParam);
769
647
  let text = `${indent.get()}${reqVarName}, err := client.${method.naming.requestMethod}(${reqParams})\n`;
770
- const zeroResp = getZeroReturnValue(method, "op");
648
+ const zeroResp = getZeroReturnValue(method);
771
649
  text += `${indent.get()}${helpers.buildErrCheck(indent, "err", zeroResp)}\n`;
772
650
  return text;
773
651
  }
@@ -783,7 +661,7 @@ function callCreateRequestWithErrCheck(method, reqVarName, indent, optionsParam)
783
661
  */
784
662
  function callPipelineDoWithErrCheck(method, reqVarName, respVarName, indent) {
785
663
  let text = `${indent.get()}${respVarName}, err := client.internal.Pipeline().Do(${reqVarName})\n`;
786
- const zeroResp = getZeroReturnValue(method, "op");
664
+ const zeroResp = getZeroReturnValue(method);
787
665
  text += `${indent.get()}${helpers.buildErrCheck(indent, "err", zeroResp)}\n`;
788
666
  return text;
789
667
  }
@@ -795,21 +673,12 @@ function genRespErrorDoc(method) {
795
673
  }
796
674
  return "";
797
675
  }
798
- /**
799
- * returns the receiver definition for a client
800
- *
801
- * @param receiver the receiver for which to emit the definition
802
- * @returns the receiver definition
803
- */
804
- function getClientReceiverDefinition(receiver) {
805
- return `(${receiver.name} ${receiver.byValue ? "" : "*"}${receiver.type.name})`;
806
- }
807
676
  function generateOperation(method, options, imports, indent) {
808
677
  const params = getAPIParametersSig(method, imports);
809
678
  const returns = generateReturnsInfo(method, "op");
810
679
  let methodName = method.name;
811
680
  if (method.kind === "pageableMethod") {
812
- methodName = fixUpMethodName(method);
681
+ methodName = helpers.fixUpMethodName(method);
813
682
  }
814
683
  let text = "";
815
684
  const respErrDoc = genRespErrorDoc(method);
@@ -831,7 +700,7 @@ function generateOperation(method, options, imports, indent) {
831
700
  text += helpers.formatCommentAsBulletItem(param.name, param.docs);
832
701
  }
833
702
  }
834
- text += `func ${getClientReceiverDefinition(method.receiver)} ${methodName}(${params}) (${returns.join(", ")}) {\n`;
703
+ text += `func ${helpers.getClientReceiverDefinition(method.receiver)} ${methodName}(${params}) (${returns.join(", ")}) {\n`;
835
704
  if (method.kind === "pageableMethod") {
836
705
  text += `${indent.get()}return `;
837
706
  text += emitPagerDefinition(method, options, imports, indent);
@@ -839,7 +708,7 @@ function generateOperation(method, options, imports, indent) {
839
708
  return text;
840
709
  }
841
710
  text += `${indent.get()}var err error\n`;
842
- let operationName = `"${method.receiver.type.name}.${fixUpMethodName(method)}"`;
711
+ let operationName = `"${method.receiver.type.name}.${helpers.fixUpMethodName(method)}"`;
843
712
  if (options.generateFakes && options.injectSpans) {
844
713
  text += `${indent.get()}const operationName = ${operationName}\n`;
845
714
  operationName = "operationName";
@@ -851,962 +720,59 @@ function generateOperation(method, options, imports, indent) {
851
720
  text += `${indent.get()}ctx, endSpan := runtime.StartSpan(ctx, ${operationName}, client.internal.Tracer(), nil)\n`;
852
721
  text += `${indent.get()}defer func() { endSpan(err) }()\n`;
853
722
  }
854
- const zeroResp = getZeroReturnValue(method, "op");
855
723
  text += callCreateRequestWithErrCheck(method, "req", indent);
856
724
  text += callPipelineDoWithErrCheck(method, "req", "httpResp", indent);
857
- text += `${indent.get()}if !runtime.HasStatusCode(httpResp, ${helpers.formatStatusCodes(method.httpStatusCodes)}) {\n`;
858
- indent.push();
859
- text += `${indent.get()}err = runtime.NewResponseError(httpResp)\n`;
860
- text += `${indent.get()}return ${zeroResp}, err\n`;
861
- text += `${indent.pop().get()}}\n`;
862
- // HAB with headers response is handled in protocol responder
863
- if (method.returns.result?.kind === "headAsBooleanResult" &&
864
- method.returns.headers.length === 0) {
865
- text += `${indent.get()}return ${method.returns.name}{${method.returns.result.fieldName}: httpResp.StatusCode >= 200 && httpResp.StatusCode < 300}, nil\n`;
725
+ // NOTE: for an LRO's op method we never invoke the response handler.
726
+ // for vanilla LRO's we don't emit one, only for pageable LROs and in
727
+ // that case the response handler is invoked by the fetcher.
728
+ if (needsResponseHandler(method) && !go.isLROMethod(method)) {
729
+ // methods that return a modeled type, headers, or both call the method's response handler
730
+ text += `${indent.get()}return client.${method.naming.responseMethod}(httpResp, ${helpers.formatStatusCodes(method.httpStatusCodes)})\n`;
866
731
  }
867
732
  else {
733
+ // no response handler so we emit the status code check here
734
+ const zeroResp = getZeroReturnValue(method);
735
+ text += `${indent.get()}${helpers.buildIfBlock(indent, {
736
+ condition: `!runtime.HasStatusCode(httpResp, ${helpers.formatStatusCodes(method.httpStatusCodes)})`,
737
+ body: (indent) => `${indent.get()}return ${zeroResp}, runtime.NewResponseError(httpResp)\n`,
738
+ })}\n`;
868
739
  if (go.isLROMethod(method)) {
869
740
  text += `${indent.get()}return httpResp, nil\n`;
870
741
  }
871
- else if (needsResponseHandler(method)) {
872
- // also cheating here as at present the only param to the responder is an http.Response
873
- text += `${indent.get()}resp, err := client.${method.naming.responseMethod}(httpResp)\n`;
874
- text += `${indent.get()}return resp, err\n`;
875
- }
876
- else if (method.returns.result?.kind === "binaryResult") {
877
- text += `${indent.get()}return ${method.returns.name}{${method.returns.result.fieldName}: httpResp.Body}, nil\n`;
878
- }
879
- else {
880
- text += `${indent.get()}return ${method.returns.name}{}, nil\n`;
881
- }
882
- }
883
- text += "}\n\n";
884
- return text;
885
- }
886
- /**
887
- * emits Go code to set ContentType on a MultipartContent variable if it has a fixed content type.
888
- * handles both direct MultipartContent and slices of MultipartContent.
889
- * returns the empty string if there's nothing to set.
890
- *
891
- * @param paramName the name of the multipart param
892
- * @param wireType the underlying type of the multipart param
893
- * @param indent the indentation helper currently in scope
894
- * @returns setter code or the empty string
895
- */
896
- function emitMultipartContentTypeSetter(paramName, wireType, indent) {
897
- let text = "";
898
- const unwrapped = helpers.recursiveUnwrapMapSlice(wireType);
899
- if (unwrapped.kind !== "multipartContent" || !unwrapped.contentType) {
900
- return text;
901
- }
902
- switch (wireType.kind) {
903
- case "multipartContent":
904
- text += `${indent.get()}${paramName}.ContentType = ${unwrapped.contentType.literal}\n`;
905
- break;
906
- case "slice":
907
- text += `${indent.get()}for i := range ${paramName} {\n`;
908
- text += `${indent.push().get()}${paramName}[i].ContentType = ${unwrapped.contentType.literal}\n`;
909
- text += `${indent.pop().get()}}\n`;
910
- break;
911
- }
912
- return text;
913
- }
914
- function createProtocolRequest(azureARM, method, imports, indent) {
915
- let name = method.name;
916
- if (method.kind !== "nextPageMethod") {
917
- name = method.naming.requestMethod;
918
- }
919
- for (const param of method.parameters) {
920
- if (param.location !== "method" || !go.isRequiredParameter(param.style)) {
921
- continue;
922
- }
923
- imports.addForType(param.type);
924
- }
925
- const returns = ["*policy.Request", "error"];
926
- let text = `${helpers.comment(name, "// ")} creates the ${method.name} request.\n`;
927
- text += `func ${getClientReceiverDefinition(method.receiver)} ${name}(${helpers.getCreateRequestParametersSig(method)}) (${returns.join(", ")}) {\n`;
928
- const hostParams = new Array();
929
- for (const parameter of method.receiver.type.parameters) {
930
- if (parameter.kind === "uriParam") {
931
- hostParams.push(parameter);
932
- }
933
- }
934
- let hostParam;
935
- if (azureARM) {
936
- hostParam = "client.internal.Endpoint()";
937
- }
938
- else if (method.receiver.type.instance?.kind === "templatedHost") {
939
- imports.add("strings");
940
- // we have a templated host
941
- text += `${indent.get()}host := "${method.receiver.type.instance.path}"\n`;
942
- // get all the host params on the client
943
- for (const hostParam of hostParams) {
944
- text += `${indent.get()}host = strings.ReplaceAll(host, "{${hostParam.uriPathSegment}}", ${helpers.formatValue(`client.${hostParam.name}`, hostParam.type, imports)})\n`;
945
- }
946
- // check for any method local host params
947
- for (const param of method.parameters) {
948
- if (param.location === "method" && param.kind === "uriParam") {
949
- text += `${indent.get()}host = strings.ReplaceAll(host, "{${param.uriPathSegment}}", ${helpers.formatValue(helpers.getParamName(param), param.type, imports)})\n`;
950
- }
951
- }
952
- hostParam = "host";
953
- }
954
- else if (hostParams.length === 1) {
955
- // simple parameterized host case
956
- hostParam = "client." + hostParams[0].name;
957
- }
958
- else {
959
- throw new CodegenError("InternalError", `no host or endpoint defined for method ${method.receiver.type.name}.${method.name}`);
960
- }
961
- const methodParamGroups = helpers.getMethodParamGroups(method);
962
- const hasPathParams = methodParamGroups.pathParams.length > 0;
963
- // storage needs the client.u to be the source-of-truth for the full path.
964
- // however, swagger requires that all operations specify a path, which is at odds with storage.
965
- // to work around this, storage specifies x-ms-path paths with path params but doesn't
966
- // actually reference the path params (i.e. no params with which to replace the tokens).
967
- // so, if a path contains tokens but there are no path params, skip emitting the path.
968
- const pathStr = method.httpPath;
969
- const pathContainsParms = pathStr.includes("{");
970
- if (hasPathParams || (!pathContainsParms && pathStr.length > 1)) {
971
- // there are path params, or the path doesn't contain tokens and is not "/" so emit it
972
- text += `${indent.get()}urlPath := "${method.httpPath}"\n`;
973
- hostParam = `runtime.JoinPaths(${hostParam}, urlPath)`;
974
- }
975
- // helper to build nil checks for param groups
976
- const emitParamGroupCheck = function (param) {
977
- if (!param.group) {
978
- throw new CodegenError("InternalError", `emitParamGroupCheck called for ungrouped parameter ${param.name}`);
979
- }
980
- let client = "";
981
- if (param.location === "client") {
982
- client = "client.";
983
- }
984
- const paramGroupName = naming.uncapitalize(param.group.name);
985
- let optionalParamGroupCheck = `${client}${paramGroupName} != nil && `;
986
- if (param.group.required) {
987
- optionalParamGroupCheck = "";
988
- }
989
- return `${indent.get()}if ${optionalParamGroupCheck}${client}${paramGroupName}.${naming.capitalize(param.name)} != nil {\n`;
990
- };
991
- if (hasPathParams) {
992
- // swagger defines path params, emit path and replace tokens
993
- imports.add("strings");
994
- // replace path parameters
995
- for (const pp of methodParamGroups.pathParams) {
996
- let paramValue;
997
- let optionalPathSep = false;
998
- if (pp.style === "literal") {
999
- // literals are always scalar types and require no empty checks
1000
- paramValue = helpers.formatParamValue(pp, imports, indent);
1001
- }
1002
- else if (pp.style === "required" || pp.location === "client") {
1003
- // NOTE: we include client params here since they behave
1004
- // like required params (i.e. not grouped).
1005
- // emit check to ensure path param isn't an empty string
1006
- if (pp.kind === "pathScalarParam") {
1007
- const choiceIsString = function (type) {
1008
- return type.kind === "constant" && type.type === "string";
1009
- };
1010
- // we only need to do this for params that have an underlying type of string
1011
- if ((pp.type.kind === "string" || choiceIsString(pp.type)) && !pp.omitEmptyStringCheck) {
1012
- const paramName = helpers.getParamName(pp);
1013
- imports.add("errors");
1014
- text += `${indent.get()}if ${paramName} == "" {\n`;
1015
- text += `${indent.push().get()}return nil, errors.New("parameter ${paramName} cannot be empty")\n`;
1016
- text += `${indent.pop().get()}}\n`;
1017
- }
1018
- }
1019
- paramValue = helpers.formatParamValue(pp, imports, indent);
1020
- // for collection-based path params, we emit the empty check
1021
- // after calling helpers.formatParamValue as that will have the
1022
- // var name that contains the slice.
1023
- if (pp.kind === "pathCollectionParam") {
1024
- const paramName = helpers.getParamName(pp);
1025
- const joinedParamName = `${paramName}Param`;
1026
- text += `${indent.get()}${joinedParamName} := ${paramValue}\n`;
1027
- imports.add("errors");
1028
- text += `${indent.get()}if len(${joinedParamName}) == 0 {\n`;
1029
- text += `${indent.push().get()}return nil, errors.New("parameter ${paramName} cannot be empty")\n`;
1030
- text += `${indent.pop().get()}}\n`;
1031
- paramValue = joinedParamName;
1032
- }
1033
- }
1034
- else if (go.isClientSideDefault(pp.style)) {
1035
- const defaultValue = naming.uncapitalize(pp.name) + "Default";
1036
- text += `${indent.get()}${defaultValue} := ${helpers.formatLiteralValue(pp.style.defaultValue, true)}\n`;
1037
- text += emitParamGroupCheck(pp);
1038
- text += `${indent.push().get()}${defaultValue} = ${helpers.getParamName(pp)}\n`;
1039
- text += `${indent.pop().get()}}\n`;
1040
- paramValue = helpers.formatValue(defaultValue, pp.type, imports);
1041
- }
1042
- else {
1043
- // param isn't required, so emit a local var with
1044
- // the correct default value, then populate it with
1045
- // the optional value when set.
1046
- paramValue = `optional${naming.capitalize(pp.name)}`;
1047
- text += `${indent.get()}${paramValue} := ""\n`;
1048
- text += emitParamGroupCheck(pp);
1049
- text += `${indent.push().get()}${paramValue} = ${helpers.formatParamValue(pp, imports, indent)}\n`;
1050
- text += `${indent.pop().get()}}\n`;
1051
- // there are two cases for optional path params.
1052
- // - /foo/bar/{optional}
1053
- // - /foo/bar{/optional}
1054
- // for the second case, we need to include a forward slash
1055
- if (method.httpPath[method.httpPath.indexOf(`{${pp.pathSegment}}`) - 1] !== "/") {
1056
- optionalPathSep = true;
1057
- }
1058
- }
1059
- const emitPathEscape = function () {
1060
- if (pp.isEncoded) {
1061
- imports.add("net/url");
1062
- return `url.PathEscape(${paramValue})`;
1063
- }
1064
- return paramValue;
1065
- };
1066
- if (optionalPathSep) {
1067
- text += `${indent.get()}if len(${paramValue}) > 0 {\n`;
1068
- text += `${indent.push().get()}${paramValue} = "/"+${emitPathEscape()}\n`;
1069
- text += `${indent.pop().get()}}\n`;
1070
- }
1071
- else {
1072
- paramValue = emitPathEscape();
1073
- }
1074
- text += `${indent.get()}urlPath = strings.ReplaceAll(urlPath, "{${pp.pathSegment}}", ${paramValue})\n`;
1075
- }
1076
- }
1077
- text += `${indent.get()}req, err := runtime.NewRequest(ctx, http.Method${naming.capitalize(method.httpMethod)}, ${hostParam})\n`;
1078
- text += `${indent.get()}if err != nil {\n`;
1079
- text += `${indent.push().get()}return nil, err\n`;
1080
- text += `${indent.pop().get()}}\n`;
1081
- // add query parameters
1082
- const encodedParams = methodParamGroups.encodedQueryParams;
1083
- const unencodedParams = methodParamGroups.unencodedQueryParams;
1084
- const emitQueryParam = function (qp, setter) {
1085
- let qpText;
1086
- if (qp.location === "method" && go.isClientSideDefault(qp.style)) {
1087
- qpText = emitClientSideDefault(qp, qp.style, (name, val) => {
1088
- return `${indent.get()}reqQP.Set(${name}, ${val})`;
1089
- }, imports, indent);
1090
- }
1091
- else if (go.isRequiredParameter(qp.style) ||
1092
- go.isLiteralParameter(qp.style) ||
1093
- (qp.location === "client" && go.isClientSideDefault(qp.style))) {
1094
- qpText = `${indent.get()}${setter}\n`;
1095
- }
1096
- else if (qp.location === "client" && !qp.group) {
1097
- // global optional param
1098
- qpText = `${indent.get()}if client.${qp.name} != nil {\n`;
1099
- qpText += `${indent.push().get()}${setter}\n`;
1100
- qpText += `${indent.pop().get()}}\n`;
1101
- }
1102
- else {
1103
- qpText = emitParamGroupCheck(qp);
1104
- qpText += `${indent.push().get()}${setter}\n`;
1105
- qpText += `${indent.pop().get()}}\n`;
1106
- }
1107
- return qpText;
1108
- };
1109
- // emit encoded params first
1110
- if (encodedParams.length > 0) {
1111
- text += `${indent.get()}reqQP := req.Raw().URL.Query()\n`;
1112
- for (const qp of encodedParams.sort((a, b) => {
1113
- return helpers.sortAscending(a.queryParameter, b.queryParameter);
1114
- })) {
1115
- let setter;
1116
- if (qp.kind === "queryCollectionParam" && qp.collectionFormat === "multi") {
1117
- setter = `for _, qv := range ${helpers.getParamName(qp)} {\n`;
1118
- // emit a type conversion for the qv based on the array's element type
1119
- let queryVal;
1120
- const arrayQP = qp.type;
1121
- switch (arrayQP.elementType.kind) {
1122
- case "constant":
1123
- switch (arrayQP.elementType.type) {
1124
- case "string":
1125
- queryVal = "string(qv)";
1126
- break;
1127
- default:
1128
- imports.add("fmt");
1129
- queryVal = 'fmt.Sprintf("%d", qv)';
1130
- }
1131
- break;
1132
- case "string":
1133
- queryVal = "qv";
1134
- break;
1135
- default:
1136
- imports.add("fmt");
1137
- queryVal = 'fmt.Sprintf("%v", qv)';
1138
- }
1139
- setter += `${indent.push().get()}reqQP.Add("${qp.queryParameter}", ${queryVal})\n`;
1140
- setter += `${indent.pop().get()}}`;
1141
- }
1142
- else {
1143
- // cannot initialize setter to this value as helpers.formatParamValue() can change imports
1144
- setter = `reqQP.Set("${qp.queryParameter}", ${helpers.formatParamValue(qp, imports, indent)})`;
1145
- }
1146
- text += emitQueryParam(qp, setter);
1147
- }
1148
- // reqQP.Encode() encodes space chars as '+' which is application/x-www-form-urlencoded
1149
- // thus not applicable for URIs. the correct URI encoding for SP is %20. note that literal '+'
1150
- // characters are encoded by reqQP.Encode() as %2B so there's no risk of replacing them.
1151
- // see https://www.rfc-editor.org/rfc/rfc3986 sections 2.1, 2.2, and 3.4
1152
- imports.add("strings");
1153
- text += `${indent.get()}req.Raw().URL.RawQuery = strings.ReplaceAll(reqQP.Encode(), "+", "%20")\n`;
1154
- }
1155
- // tack on any unencoded params to the end
1156
- if (unencodedParams.length > 0) {
1157
- if (encodedParams.length > 0) {
1158
- text += `${indent.get()}unencodedParams := []string{req.Raw().URL.RawQuery}\n`;
1159
- }
1160
- else {
1161
- text += `${indent.get()}unencodedParams := []string{}\n`;
1162
- }
1163
- for (const qp of unencodedParams.sort((a, b) => {
1164
- return helpers.sortAscending(a.queryParameter, b.queryParameter);
1165
- })) {
1166
- let setter;
1167
- if (qp.kind === "queryCollectionParam" && qp.collectionFormat === "multi") {
1168
- setter = `for _, qv := range ${helpers.getParamName(qp)} {\n`;
1169
- setter += `${indent.push().get()}unencodedParams = append(unencodedParams, "${qp.queryParameter}="+qv)\n`;
1170
- setter += `${indent.pop().get()}}`;
1171
- }
1172
- else {
1173
- setter = `unencodedParams = append(unencodedParams, "${qp.queryParameter}="+${helpers.formatParamValue(qp, imports, indent)})`;
1174
- }
1175
- text += emitQueryParam(qp, setter);
1176
- }
1177
- imports.add("strings");
1178
- text += `${indent.get()}req.Raw().URL.RawQuery = strings.Join(unencodedParams, "&")\n`;
1179
- }
1180
- if (method.kind !== "nextPageMethod" && method.returns.result?.kind === "binaryResult") {
1181
- // skip auto-body downloading for binary stream responses
1182
- text += `${indent.get()}runtime.SkipBodyDownload(req)\n`;
1183
- }
1184
- // add specific request headers
1185
- const emitHeaderSet = function (headerParam) {
1186
- if (headerParam.kind === "headerMapParam") {
1187
- let headerText = `${indent.get()}for k, v := range ${helpers.getParamName(headerParam)} {\n`;
1188
- headerText += `${indent.push().get()}if v != nil {\n`;
1189
- headerText += `${indent.push().get()}req.Raw().Header["${headerParam.headerName}"+k] = []string{*v}\n`;
1190
- headerText += `${indent.pop().get()}}\n`;
1191
- headerText += `${indent.pop().get()}}\n`;
1192
- return headerText;
1193
- }
1194
- else if (headerParam.location === "method" && go.isClientSideDefault(headerParam.style)) {
1195
- return emitClientSideDefault(headerParam, headerParam.style, (name, val) => {
1196
- return `${indent.get()}req.Raw().Header[${name}] = []string{${val}}`;
1197
- }, imports, indent);
1198
- }
1199
- else {
1200
- return `${indent.get()}req.Raw().Header["${headerParam.headerName}"] = []string{${helpers.formatParamValue(headerParam, imports, indent)}}\n`;
1201
- }
1202
- };
1203
- let contentType;
1204
- for (const param of methodParamGroups.headerParams.sort((a, b) => {
1205
- return helpers.sortAscending(a.headerName, b.headerName);
1206
- })) {
1207
- if (param.headerName.match(/^content-type$/i)) {
1208
- // canonicalize content-type as req.SetBody checks for it via its canonicalized name :(
1209
- param.headerName = "Content-Type";
1210
- // there's a corner case where we have a content-type param with no body
1211
- // param. for this case we still need to set the header inline.
1212
- const bodyParam = methodParamGroups.bodyParam;
1213
- if (bodyParam?.bodyFormat === "binary" || bodyParam?.bodyFormat === "Text") {
1214
- // if the content-type is from a param, then the param will be passed
1215
- // explicitly to runtime.SetBody() so don't emit code to set it inline.
1216
- // NOTE: only binary/text payloads call runtime.SetBody().
1217
- if (go.isClientSideDefault(param.style)) {
1218
- text += emitClientSideDefault(param, param.style, () => "", imports, indent);
1219
- continue;
1220
- }
1221
- else if (param.style === "required") {
1222
- continue;
1223
- }
1224
- }
1225
- }
1226
- if (param.headerName === "Content-Type" && param.style === "literal") {
1227
- // the content-type header will be set as part of emitSetBodyWithErrCheck
1228
- // to handle cases where the body param is optional. we don't want to set
1229
- // the content-type if the body is nil.
1230
- // we do it like this as tsp specifies content-type while swagger does not.
1231
- contentType = helpers.formatParamValue(param, imports, indent);
1232
- }
1233
- else if (go.isRequiredParameter(param.style) ||
1234
- go.isLiteralParameter(param.style) ||
1235
- go.isClientSideDefault(param.style)) {
1236
- text += emitHeaderSet(param);
1237
- }
1238
- else if (param.location === "client" && !param.group) {
1239
- // global optional param
1240
- text += `${indent.get()}if client.${param.name} != nil {\n`;
1241
- indent.push();
1242
- text += emitHeaderSet(param);
1243
- indent.pop();
1244
- text += `${indent.get()}}\n`;
1245
- }
1246
- else {
1247
- text += emitParamGroupCheck(param);
1248
- indent.push();
1249
- text += emitHeaderSet(param);
1250
- indent.pop();
1251
- text += `${indent.get()}}\n`;
1252
- }
1253
- }
1254
- // note that these are mutually exclusive
1255
- const bodyParam = methodParamGroups.bodyParam;
1256
- const formBodyParams = methodParamGroups.formBodyParams;
1257
- const multipartBodyParams = methodParamGroups.multipartBodyParams;
1258
- const partialBodyParams = methodParamGroups.partialBodyParams;
1259
- const emitSetBodyWithErrCheck = function (setBodyParam, contentType) {
1260
- let content = "";
1261
- if (contentType) {
1262
- content += `${indent.get()}req.Raw().Header["Content-Type"] = []string{${contentType}}\n`;
1263
- }
1264
- content += `${indent.get()}if err := ${setBodyParam}; err != nil {\n`;
1265
- content += `${indent.push().get()}return nil, err\n`;
1266
- content += `${indent.pop().get()}}\n`;
1267
- return content;
1268
- };
1269
- if (bodyParam) {
1270
- /** returns the source value for the content type */
1271
- const getContentTypeValue = function (src) {
1272
- switch (src.kind) {
1273
- case "literal":
1274
- return helpers.formatLiteralValue(src, false);
1275
- case "parameterRef": {
1276
- // find the param
1277
- for (const param of method.parameters) {
1278
- if (param.kind === "headerScalarParam" && param.name === src.name) {
1279
- if (go.isClientSideDefault(param.style)) {
1280
- return getClientSideDefaultVarName(param);
1281
- }
1282
- let paramName = helpers.getParamName(param);
1283
- if (param.type.kind === "constant") {
1284
- paramName = `string(${paramName})`;
1285
- }
1286
- return paramName;
1287
- }
1288
- }
1289
- throw new CodegenError("InternalError", `didn't find parameter reference ${src.name}`);
1290
- }
1291
- }
1292
- };
1293
- if (bodyParam.bodyFormat === "JSON" || bodyParam.bodyFormat === "XML") {
1294
- // default to the body param name
1295
- let body = helpers.getParamName(bodyParam);
1296
- if (bodyParam.type.kind === "literal") {
1297
- // if the value is constant, embed it directly
1298
- body = helpers.formatLiteralValue(bodyParam.type, true);
1299
- }
1300
- else if (bodyParam.bodyFormat === "XML" && bodyParam.type.kind === "slice") {
1301
- // for XML payloads, create a wrapper type if the payload is an array
1302
- imports.add("encoding/xml");
1303
- text += `${indent.get()}type wrapper struct {\n`;
1304
- indent.push();
1305
- let tagName;
1306
- if (bodyParam.xml?.wrapper) {
1307
- tagName = bodyParam.xml.wrapper;
1308
- }
1309
- else {
1310
- tagName = go.getTypeDeclaration(bodyParam.type, method.receiver.type.pkg);
1311
- }
1312
- text += `${indent.get()}XMLName xml.Name \`xml:"${tagName}"\`\n`;
1313
- const fieldName = naming.capitalize(bodyParam.name);
1314
- let tag = go.getTypeDeclaration(bodyParam.type.elementType, method.receiver.type.pkg);
1315
- if (bodyParam.type.elementType.kind === "model" && bodyParam.type.elementType.xml?.name) {
1316
- tag = bodyParam.type.elementType.xml.name;
1317
- }
1318
- text += `${indent.get()}${fieldName} *${go.getTypeDeclaration(bodyParam.type, method.receiver.type.pkg)} \`xml:"${tag}"\`\n`;
1319
- text += `${indent.pop().get()}}\n`;
1320
- let addr = "&";
1321
- if (!go.isRequiredParameter(bodyParam.style) && !bodyParam.byValue) {
1322
- addr = "";
1323
- }
1324
- body = `wrapper{${fieldName}: ${addr}${body}}`;
1325
- }
1326
- else if (bodyParam.type.kind === "time") {
1327
- // utc datetimes are normalized to UTC before serialization. non-RFC3339
1328
- // formats are wrapped in the internal time type; RFC3339 relies on the
1329
- // default time.Time JSON marshaler so it only needs the UTC conversion.
1330
- const bodyVal = bodyParam.type.utc ? `${body}.UTC()` : body;
1331
- if (bodyParam.type.format !== "RFC3339") {
1332
- imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime");
1333
- body = `datetime.${bodyParam.type.format}(${bodyVal})`;
1334
- }
1335
- else {
1336
- body = bodyVal;
1337
- }
1338
- }
1339
- else if (isArrayOfDateTimeForMarshalling(bodyParam.type)) {
1340
- const timeInfo = isArrayOfDateTimeForMarshalling(bodyParam.type);
1341
- let elementPtr = "*";
1342
- if (timeInfo?.elemByVal) {
1343
- elementPtr = "";
1344
- }
1345
- imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime");
1346
- text += `${indent.get()}aux := make([]${elementPtr}datetime.${timeInfo?.format}, len(${body}))\n`;
1347
- text += `${indent.get()}for i := 0; i < len(${body}); i++ {\n`;
1348
- if (timeInfo?.utc && elementPtr === "*") {
1349
- text += `${indent.push().get()}if ${body}[i] != nil {\n`;
1350
- text += `${indent.push().get()}utcTime := ${body}[i].UTC()\n`;
1351
- text += `${indent.get()}aux[i] = (*datetime.${timeInfo?.format})(&utcTime)\n`;
1352
- text += `${indent.pop().get()}}\n`;
1353
- indent.pop();
1354
- }
1355
- else {
1356
- const utcCall = timeInfo?.utc ? ".UTC()" : "";
1357
- text += `${indent.push().get()}aux[i] = (${elementPtr}datetime.${timeInfo?.format})(${body}[i]${utcCall})\n`;
1358
- indent.pop();
1359
- }
1360
- text += `${indent.get()}}\n`;
1361
- body = "aux";
1362
- }
1363
- else if (isMapOfDateTime(bodyParam.type)) {
1364
- const timeInfo = isMapOfDateTime(bodyParam.type);
1365
- imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime");
1366
- text += `${indent.get()}aux := map[string]*datetime.${timeInfo?.format}{}\n`;
1367
- text += `${indent.get()}for k, v := range ${body} {\n`;
1368
- if (timeInfo?.utc) {
1369
- text += `${indent.push().get()}if v != nil {\n`;
1370
- text += `${indent.push().get()}utcTime := v.UTC()\n`;
1371
- text += `${indent.get()}aux[k] = (*datetime.${timeInfo?.format})(&utcTime)\n`;
1372
- text += `${indent.pop().get()}} else {\n`;
1373
- text += `${indent.push().get()}aux[k] = nil\n`;
1374
- text += `${indent.pop().get()}}\n`;
1375
- indent.pop();
1376
- }
1377
- else {
1378
- text += `${indent.push().get()}aux[k] = (*datetime.${timeInfo?.format})(v)\n`;
1379
- indent.pop();
1380
- }
1381
- text += `${indent.get()}}\n`;
1382
- body = "aux";
1383
- }
1384
- let setBody = `runtime.MarshalAs${getMediaFormat(bodyParam.type, bodyParam.bodyFormat, `req, ${body}`)}`;
1385
- if (bodyParam.type.kind === "rawJSON") {
1386
- imports.add("bytes");
1387
- imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming");
1388
- setBody = `req.SetBody(streaming.NopCloser(bytes.NewReader(${body})), "application/${bodyParam.bodyFormat.toLowerCase()}")`;
1389
- }
1390
- if (go.isRequiredParameter(bodyParam.style) || go.isLiteralParameter(bodyParam.style)) {
1391
- text += emitSetBodyWithErrCheck(setBody, contentType);
1392
- text += `${indent.get()}return req, nil\n`;
1393
- }
1394
- else {
1395
- text += emitParamGroupCheck(bodyParam);
1396
- indent.push();
1397
- text += emitSetBodyWithErrCheck(setBody, contentType);
1398
- text += `${indent.get()}return req, nil\n`;
1399
- indent.pop();
1400
- text += `${indent.get()}}\n`;
1401
- text += `${indent.get()}return req, nil\n`;
1402
- }
1403
- }
1404
- else if (bodyParam.bodyFormat === "binary") {
1405
- if (go.isRequiredParameter(bodyParam.style)) {
1406
- text += emitSetBodyWithErrCheck(`req.SetBody(${bodyParam.name}, ${getContentTypeValue(bodyParam.contentType)})`, contentType);
1407
- text += `${indent.get()}return req, nil\n`;
1408
- }
1409
- else {
1410
- text += emitParamGroupCheck(bodyParam);
1411
- indent.push();
1412
- text += emitSetBodyWithErrCheck(`req.SetBody(${helpers.getParamName(bodyParam)}, ${getContentTypeValue(bodyParam.contentType)})`, contentType);
1413
- text += `${indent.get()}return req, nil\n`;
1414
- indent.pop();
1415
- text += `${indent.get()}}\n`;
1416
- text += `${indent.get()}return req, nil\n`;
1417
- }
1418
- }
1419
- else if (bodyParam.bodyFormat === "Text") {
1420
- imports.add("strings");
1421
- imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming");
1422
- if (go.isRequiredParameter(bodyParam.style)) {
1423
- text += `${indent.get()}body := streaming.NopCloser(strings.NewReader(${bodyParam.name}))\n`;
1424
- text += emitSetBodyWithErrCheck(`req.SetBody(body, ${getContentTypeValue(bodyParam.contentType)})`, contentType);
1425
- text += `${indent.get()}return req, nil\n`;
1426
- }
1427
- else {
1428
- text += emitParamGroupCheck(bodyParam);
1429
- indent.push();
1430
- text += `${indent.get()}body := streaming.NopCloser(strings.NewReader(${helpers.getParamName(bodyParam)}))\n`;
1431
- text += emitSetBodyWithErrCheck(`req.SetBody(body, ${getContentTypeValue(bodyParam.contentType)})`, contentType);
1432
- text += `${indent.get()}return req, nil\n`;
1433
- indent.pop();
1434
- text += `${indent.get()}}\n`;
1435
- text += `${indent.get()}return req, nil\n`;
1436
- }
1437
- }
1438
- }
1439
- else if (partialBodyParams.length > 0) {
1440
- // partial body params are discrete params that are all fields within an internal struct.
1441
- // define and instantiate an instance of the wire type, using the values from each param.
1442
- text += `${indent.get()}body := struct {\n`;
1443
- indent.push();
1444
- for (const partialBodyParam of partialBodyParams) {
1445
- text += `${indent.get()}${naming.capitalize(partialBodyParam.serializedName)} ${helpers.star(partialBodyParam.byValue)}${go.getTypeDeclaration(partialBodyParam.type, method.receiver.type.pkg)} \`${partialBodyParam.format.toLowerCase()}:"${partialBodyParam.serializedName}"\`\n`;
1446
- }
1447
- indent.pop();
1448
- text += `${indent.get()}}{\n`;
1449
- indent.push();
1450
- // required params are emitted as initializers in the struct literal
1451
- for (const partialBodyParam of partialBodyParams) {
1452
- if (go.isRequiredParameter(partialBodyParam.style)) {
1453
- text += `${indent.get()}${naming.capitalize(partialBodyParam.serializedName)}: ${naming.uncapitalize(partialBodyParam.name)},\n`;
1454
- }
1455
- }
1456
- indent.pop();
1457
- text += `${indent.get()}}\n`;
1458
- // now populate any optional params from the options type
1459
- for (const partialBodyParam of partialBodyParams) {
1460
- if (!go.isRequiredParameter(partialBodyParam.style)) {
1461
- text += emitParamGroupCheck(partialBodyParam);
1462
- text += `${indent.push().get()}body.${naming.capitalize(partialBodyParam.serializedName)} = options.${naming.capitalize(partialBodyParam.name)}\n`;
1463
- text += `${indent.pop().get()}}\n`;
1464
- }
1465
- }
1466
- // TODO: spread params are JSON only https://github.com/Azure/autorest.go/issues/1455
1467
- text += `${indent.get()}req.Raw().Header["Content-Type"] = []string{"application/json"}\n`;
1468
- text += `${indent.get()}if err := runtime.MarshalAsJSON(req, body); err != nil {\n`;
1469
- text += `${indent.push().get()}return nil, err\n`;
1470
- text += `${indent.pop().get()}}\n`;
1471
- text += `${indent.get()}return req, nil\n`;
1472
- }
1473
- else if (multipartBodyParams.length > 0) {
1474
- // emit content type setters for direct MultipartContent params with a fixed content type.
1475
- // this handles the case where the param itself is a MultipartContent or a slice of them
1476
- // (i.e. not wrapped in a model struct with toMultipartFormData()).
1477
- // note that tsp only allows homogeneous content types, which is why it's safe
1478
- // to unwrap the first param's type and check its contentType field.
1479
- text += emitMultipartContentTypeSetter(multipartBodyParams[0].name, multipartBodyParams[0].type, indent);
1480
- if (multipartBodyParams.length === 1 &&
1481
- multipartBodyParams[0].type.kind === "model" &&
1482
- multipartBodyParams[0].type.annotations.multipartFormData) {
1483
- // emit content type setters for model fields that have a fixed content type.
1484
- // toMultipartFormData() converts the model to map[string]any but doesn't set ContentType,
1485
- // so we must set it on each MultipartContent field before the conversion.
1486
- for (const field of multipartBodyParams[0].type.fields) {
1487
- text += emitMultipartContentTypeSetter(`${multipartBodyParams[0].name}.${field.name}`, field.type, indent);
742
+ else if (method.returns.result) {
743
+ switch (method.returns.result.kind) {
744
+ case "binaryResult":
745
+ text += `${indent.get()}return ${method.returns.name}{${method.returns.result.fieldName}: httpResp.Body}, nil\n`;
746
+ break;
747
+ case "headAsBooleanResult":
748
+ text += `${indent.get()}return ${method.returns.name}{${method.returns.result.fieldName}: httpResp.StatusCode >= 200 && httpResp.StatusCode < 300}, nil\n`;
749
+ break;
750
+ default:
751
+ // we should never get here as the remaining kinds are all modeled results
752
+ // thus should have been handled by the needsResponseHandler check earlier
753
+ throw new CodegenError("InternalError", `unexpected method result kind ${method.returns.result.kind}`);
1488
754
  }
1489
- text += `${indent.get()}formData, err := ${multipartBodyParams[0].name}.toMultipartFormData()\n`;
1490
- text += `${indent.get()}if err != nil {\n`;
1491
- text += `${indent.push().get()}return nil, err\n`;
1492
- text += `${indent.pop().get()}}\n`;
1493
755
  }
1494
756
  else {
1495
- text += `${indent.get()}formData := map[string]any{}\n`;
1496
- for (const param of multipartBodyParams) {
1497
- const setter = `formData["${param.name}"] = ${helpers.getParamName(param)}`;
1498
- if (go.isRequiredParameter(param.style)) {
1499
- text += `${indent.get()}${setter}\n`;
1500
- }
1501
- else {
1502
- text += emitParamGroupCheck(param);
1503
- text += `${indent.push().get()}${setter}\n`;
1504
- text += `${indent.pop().get()}}\n`;
1505
- }
1506
- }
1507
- }
1508
- text += `${indent.get()}if err := runtime.SetMultipartFormData(req, formData); err != nil {\n`;
1509
- text += `${indent.push().get()}return nil, err\n`;
1510
- text += `${indent.pop().get()}}\n`;
1511
- text += `${indent.get()}return req, nil\n`;
1512
- }
1513
- else if (formBodyParams.length > 0) {
1514
- const emitFormData = function (param, setter) {
1515
- let formDataText;
1516
- if (go.isRequiredParameter(param.style)) {
1517
- formDataText = `${indent.get()}${setter}\n`;
1518
- }
1519
- else {
1520
- formDataText = emitParamGroupCheck(param);
1521
- formDataText += `${indent.push().get()}${setter}\n`;
1522
- formDataText += `${indent.pop().get()}}\n`;
1523
- }
1524
- return formDataText;
1525
- };
1526
- imports.add("net/url");
1527
- imports.add("strings");
1528
- imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming");
1529
- text += `${indent.get()}formData := url.Values{}\n`;
1530
- // find all the form body params
1531
- for (const param of formBodyParams) {
1532
- const setter = `formData.Set("${param.formDataName}", ${helpers.formatParamValue(param, imports, indent)})`;
1533
- text += emitFormData(param, setter);
757
+ // no result type, just response envelope
758
+ text += `${indent.get()}return ${zeroResp}, nil\n`;
1534
759
  }
1535
- text += `${indent.get()}body := streaming.NopCloser(strings.NewReader(formData.Encode()))\n`;
1536
- text += emitSetBodyWithErrCheck('req.SetBody(body, "application/x-www-form-urlencoded")');
1537
- text += `${indent.get()}return req, nil\n`;
1538
- }
1539
- else {
1540
- text += `${indent.get()}return req, nil\n`;
1541
760
  }
1542
761
  text += "}\n\n";
1543
762
  return text;
1544
763
  }
1545
- /**
1546
- * returns the var name to use for a param's client-side default value
1547
- *
1548
- * @param param the param for which to name the var
1549
- * @returns the var name
1550
- */
1551
- function getClientSideDefaultVarName(param) {
1552
- return naming.uncapitalize(param.name) + "Default";
1553
- }
1554
- function emitClientSideDefault(param, csd, setterFormat, imports, indent) {
1555
- const defaultVar = getClientSideDefaultVarName(param);
1556
- let text = `${indent.get()}${defaultVar} := ${helpers.formatLiteralValue(csd.defaultValue, true)}\n`;
1557
- text += `${indent.get()}if options != nil && options.${naming.capitalize(param.name)} != nil {\n`;
1558
- text += `${indent.push().get()}${defaultVar} = *options.${naming.capitalize(param.name)}\n`;
1559
- text += `${indent.pop().get()}}\n`;
1560
- let serializedName;
1561
- switch (param.kind) {
1562
- case "headerCollectionParam":
1563
- case "headerScalarParam":
1564
- serializedName = param.headerName;
1565
- break;
1566
- case "queryCollectionParam":
1567
- case "queryScalarParam":
1568
- serializedName = param.queryParameter;
1569
- break;
1570
- }
1571
- const setterFormatText = setterFormat(`"${serializedName}"`, helpers.formatValue(defaultVar, param.type, imports));
1572
- text += setterFormatText;
1573
- // setterFormat can return the empty string in some cases.
1574
- // if it does, there's no need for an extra new-line char.
1575
- if (setterFormatText.length > 0) {
1576
- text += "\n";
1577
- }
1578
- return text;
1579
- }
1580
- function getMediaFormat(type, mediaType, param) {
1581
- let marshaller = mediaType;
1582
- let format = "";
1583
- if (type.kind === "encodedBytes") {
1584
- marshaller = "ByteArray";
1585
- format = `, runtime.Base64${type.encoding}Format`;
1586
- }
1587
- return `${marshaller}(${param}${format})`;
1588
- }
1589
- function isArrayOfDateTimeForMarshalling(paramType) {
1590
- if (paramType.kind !== "slice") {
1591
- return undefined;
1592
- }
1593
- if (paramType.elementType.kind !== "time") {
1594
- return undefined;
1595
- }
1596
- switch (paramType.elementType.format) {
1597
- case "PlainDate":
1598
- case "RFC1123":
1599
- case "RFC7231":
1600
- case "PlainTime":
1601
- case "Unix":
1602
- return {
1603
- format: paramType.elementType.format,
1604
- elemByVal: paramType.elementTypeByValue,
1605
- utc: paramType.elementType.utc,
1606
- };
1607
- case "RFC3339":
1608
- // RFC3339 normally uses the default time.Time marshaller, but utc slices
1609
- // must be normalized to UTC, which requires building the wrapper slice.
1610
- if (paramType.elementType.utc) {
1611
- return {
1612
- format: "RFC3339",
1613
- elemByVal: paramType.elementTypeByValue,
1614
- utc: true,
1615
- };
1616
- }
1617
- return undefined;
1618
- default:
1619
- return undefined;
1620
- }
1621
- }
1622
764
  // returns true if the method requires a response handler.
1623
765
  // this is used to unmarshal the response body, parse response headers, or both.
1624
766
  function needsResponseHandler(method) {
1625
- return helpers.hasSchemaResponse(method) || method.returns.headers.length > 0;
1626
- }
1627
- function generateResponseUnmarshaller(method, type, format, unmarshalTarget, imports, indent) {
1628
- let unmarshallerText = "";
1629
- const zeroValue = getZeroReturnValue(method, "handler");
1630
- if (type.kind === "time") {
1631
- // use the designated time type for unmarshalling
1632
- imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime");
1633
- unmarshallerText += `${indent.get()}var aux *datetime.${type.format}\n`;
1634
- unmarshallerText += `${indent.get()}if err := runtime.UnmarshalAs${format}(resp, &aux); err != nil {\n`;
1635
- unmarshallerText += `${indent.push().get()}return ${zeroValue}, err\n`;
1636
- unmarshallerText += `${indent.pop().get()}}\n`;
1637
- unmarshallerText += `${indent.get()}result.${helpers.getResultFieldName(method)} = (*time.Time)(aux)\n`;
1638
- return unmarshallerText;
1639
- }
1640
- else if (isArrayOfDateTime(type)) {
1641
- // unmarshalling arrays of date/time is a little more involved
1642
- const timeInfo = isArrayOfDateTime(type);
1643
- let elementPtr = "*";
1644
- if (timeInfo?.elemByVal) {
1645
- elementPtr = "";
1646
- }
1647
- imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime");
1648
- unmarshallerText += `${indent.get()}var aux []${elementPtr}datetime.${timeInfo?.format}\n`;
1649
- unmarshallerText += `${indent.get()}if err := runtime.UnmarshalAs${format}(resp, &aux); err != nil {\n`;
1650
- unmarshallerText += `${indent.push().get()}return ${zeroValue}, err\n`;
1651
- unmarshallerText += `${indent.pop().get()}}\n`;
1652
- unmarshallerText += `${indent.get()}cp := make([]${elementPtr}time.Time, len(aux))\n`;
1653
- unmarshallerText += `${indent.get()}for i := 0; i < len(aux); i++ {\n`;
1654
- unmarshallerText += `${indent.push().get()}cp[i] = (${elementPtr}time.Time)(aux[i])\n`;
1655
- unmarshallerText += `${indent.pop().get()}}\n`;
1656
- unmarshallerText += `${indent.get()}result.${helpers.getResultFieldName(method)} = cp\n`;
1657
- return unmarshallerText;
1658
- }
1659
- else if (isMapOfDateTime(type)) {
1660
- const timeInfo = isMapOfDateTime(type);
1661
- imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime");
1662
- unmarshallerText += `${indent.get()}aux := map[string]*datetime.${timeInfo?.format}{}\n`;
1663
- unmarshallerText += `${indent.get()}if err := runtime.UnmarshalAs${format}(resp, &aux); err != nil {\n`;
1664
- unmarshallerText += `${indent.push().get()}return ${zeroValue}, err\n`;
1665
- unmarshallerText += `${indent.pop().get()}}\n`;
1666
- unmarshallerText += `${indent.get()}cp := map[string]*time.Time{}\n`;
1667
- unmarshallerText += `${indent.get()}for k, v := range aux {\n`;
1668
- unmarshallerText += `${indent.push().get()}cp[k] = (*time.Time)(v)\n`;
1669
- unmarshallerText += `${indent.pop().get()}}\n`;
1670
- unmarshallerText += `${indent.get()}result.${helpers.getResultFieldName(method)} = cp\n`;
1671
- return unmarshallerText;
1672
- }
1673
- if (format === "JSON" || format === "XML") {
1674
- if (type.kind === "rawJSON") {
1675
- unmarshallerText += `${indent.get()}body, err := runtime.Payload(resp)\n`;
1676
- unmarshallerText += `${indent.get()}if err != nil {\n`;
1677
- unmarshallerText += `${indent.push().get()}return ${zeroValue}, err\n`;
1678
- unmarshallerText += `${indent.pop().get()}}\n`;
1679
- unmarshallerText += `${indent.get()}${unmarshalTarget} = body\n`;
1680
- }
1681
- else {
1682
- unmarshallerText += `${indent.get()}if err := runtime.UnmarshalAs${getMediaFormat(type, format, `resp, &${unmarshalTarget}`)}; err != nil {\n`;
1683
- unmarshallerText += `${indent.push().get()}return ${zeroValue}, err\n`;
1684
- unmarshallerText += `${indent.pop().get()}}\n`;
1685
- }
1686
- }
1687
- else if (format === "Text") {
1688
- unmarshallerText += `${indent.get()}body, err := runtime.Payload(resp)\n`;
1689
- unmarshallerText += `${indent.get()}if err != nil {\n`;
1690
- unmarshallerText += `${indent.push().get()}return ${zeroValue}, err\n`;
1691
- unmarshallerText += `${indent.pop().get()}}\n`;
1692
- let resultVar;
1693
- switch (type.kind) {
1694
- case "scalar":
1695
- resultVar = "parsedBody";
1696
- unmarshallerText += emitScalarParsing(type, "string(body)", resultVar, imports, indent);
1697
- unmarshallerText += `${indent.get()}${helpers.buildErrCheck(indent, "err", zeroValue)}\n`;
1698
- break;
1699
- case "string":
1700
- resultVar = "txt";
1701
- unmarshallerText += `${indent.get()}${resultVar} := string(body)\n`;
1702
- break;
1703
- default:
1704
- throw new CodegenError("UnsupportedTsp", `unsupported text return kind ${type.kind} for method ${method.receiver.type.name}.${method.name}`);
1705
- }
1706
- unmarshallerText += `${indent.get()}${unmarshalTarget} = &${resultVar}\n`;
1707
- }
1708
- else {
1709
- // the remaining formats should have been handled elsewhere
1710
- throw new CodegenError("InternalError", `unhandled format ${format} for operation ${method.receiver.type.name}.${method.name}`);
1711
- }
1712
- return unmarshallerText;
1713
- }
1714
- function createProtocolResponse(method, imports, indent) {
1715
- if (!needsResponseHandler(method)) {
1716
- return "";
1717
- }
1718
- const name = method.naming.responseMethod;
1719
- let text = `${helpers.comment(name, "// ")} handles the ${method.name} response.\n`;
1720
- text += `func ${getClientReceiverDefinition(method.receiver)} ${name}(resp *http.Response) (${generateReturnsInfo(method, "handler").join(", ")}) {\n`;
1721
- const addHeaders = function (headers) {
1722
- for (const header of headers) {
1723
- text += formatHeaderResponseValue(method, header, "result", `${method.returns.name}{}`, imports, indent);
1724
- }
1725
- };
1726
- const result = method.returns.result;
1727
- if (!result) {
1728
- // only headers
1729
- text += `${indent.get()}result := ${method.returns.name}{}\n`;
1730
- addHeaders(method.returns.headers);
1731
- }
1732
- else {
1733
- switch (result.kind) {
1734
- case "anyResult":
1735
- imports.add("fmt");
1736
- text += `${indent.get()}result := ${method.returns.name}{}\n`;
1737
- addHeaders(method.returns.headers);
1738
- text += `${indent.get()}switch resp.StatusCode {\n`;
1739
- for (const statusCode of method.httpStatusCodes) {
1740
- text += `${indent.get()}case ${helpers.formatStatusCodes([statusCode])}:\n`;
1741
- const resultType = result.httpStatusCodeType[statusCode];
1742
- if (!resultType) {
1743
- // the operation contains a mix of schemas and non-schema responses
1744
- continue;
1745
- }
1746
- text += `${indent.get()}var val ${go.getTypeDeclaration(resultType, method.receiver.type.pkg)}\n`;
1747
- text += generateResponseUnmarshaller(method, resultType, result.format, "val", imports, indent);
1748
- text += `${indent.get()}result.Value = val\n`;
1749
- }
1750
- text += `${indent.get()}default:\n`;
1751
- text += `${indent.push().get()}return ${getZeroReturnValue(method, "handler")}, fmt.Errorf("unhandled HTTP status code %d", resp.StatusCode)\n`;
1752
- text += `${indent.pop().get()}}\n`;
1753
- break;
1754
- case "binaryResult":
1755
- text += `${indent.get()}result := ${method.returns.name}{${result.fieldName}: resp.Body}\n`;
1756
- addHeaders(method.returns.headers);
1757
- break;
1758
- case "headAsBooleanResult":
1759
- text += `${indent.get()}result := ${method.returns.name}{${result.fieldName}: resp.StatusCode >= 200 && resp.StatusCode < 300}\n`;
1760
- addHeaders(method.returns.headers);
1761
- break;
1762
- case "modelResult":
1763
- text += `${indent.get()}result := ${method.returns.name}{}\n`;
1764
- addHeaders(method.returns.headers);
1765
- text += generateResponseUnmarshaller(method, result.modelType, result.format, `result.${helpers.getResultFieldName(method)}`, imports, indent);
1766
- break;
1767
- case "monomorphicResult":
1768
- text += `${indent.get()}result := ${method.returns.name}{}\n`;
1769
- addHeaders(method.returns.headers);
1770
- let target = `result.${helpers.getResultFieldName(method)}`;
1771
- // when unmarshalling a wrapped XML array, unmarshal into the response envelope
1772
- if (result.format === "XML" && result.monomorphicType.kind === "slice") {
1773
- target = "result";
1774
- }
1775
- text += generateResponseUnmarshaller(method, result.monomorphicType, result.format, target, imports, indent);
1776
- break;
1777
- case "polymorphicResult":
1778
- text += `${indent.get()}result := ${method.returns.name}{}\n`;
1779
- addHeaders(method.returns.headers);
1780
- text += generateResponseUnmarshaller(method, result.interface, result.format, "result", imports, indent);
1781
- break;
1782
- default:
1783
- result;
1784
- }
1785
- }
1786
- text += `${indent.get()}return result, nil\n`;
1787
- text += "}\n\n";
1788
- return text;
1789
- }
1790
- function isArrayOfDateTime(paramType) {
1791
- if (paramType.kind !== "slice") {
1792
- return undefined;
1793
- }
1794
- if (paramType.elementType.kind !== "time") {
1795
- return undefined;
1796
- }
1797
- return {
1798
- format: paramType.elementType.format,
1799
- elemByVal: paramType.elementTypeByValue,
1800
- };
1801
- }
1802
- function isMapOfDateTime(paramType) {
1803
- if (paramType.kind !== "map") {
1804
- return undefined;
1805
- }
1806
- if (paramType.valueType.kind !== "time") {
1807
- return undefined;
767
+ switch (method.returns.result?.kind) {
768
+ case "anyResult":
769
+ case "modelResult":
770
+ case "monomorphicResult":
771
+ case "polymorphicResult":
772
+ return true;
773
+ default:
774
+ return method.returns.headers.length > 0;
1808
775
  }
1809
- return { format: paramType.valueType.format, utc: paramType.valueType.utc };
1810
776
  }
1811
777
  /**
1812
778
  * returns the parameters for the public API
@@ -1846,7 +812,6 @@ function getAPIParametersSig(method, imports) {
1846
812
  // apiType describes where the return sig is used.
1847
813
  // api - for the API definition
1848
814
  // op - for the operation
1849
- // handler - for the response handler
1850
815
  function generateReturnsInfo(method, apiType) {
1851
816
  let returnType = method.returns.name;
1852
817
  switch (method.kind) {
@@ -1861,25 +826,14 @@ function generateReturnsInfo(method, apiType) {
1861
826
  returnType = `*runtime.Poller[${returnType}]`;
1862
827
  }
1863
828
  break;
1864
- case "handler":
1865
- // we only have a handler for operations that return a schema
1866
- if (method.kind !== "lroPageableMethod") {
1867
- throw new CodegenError("InternalError", `handler being generated for non-pageable LRO ${method.name} which is unexpected`);
1868
- }
1869
- break;
1870
829
  case "op":
1871
830
  returnType = "*http.Response";
1872
831
  break;
1873
832
  }
1874
833
  break;
1875
834
  case "pageableMethod":
1876
- switch (apiType) {
1877
- case "api":
1878
- case "op":
1879
- // pager operations don't return an error
1880
- return [`*runtime.Pager[${returnType}]`];
1881
- }
1882
- break;
835
+ // pager operations don't return an error
836
+ return [`*runtime.Pager[${returnType}]`];
1883
837
  }
1884
838
  return [returnType, "error"];
1885
839
  }
@@ -1889,15 +843,15 @@ function generateLROBeginMethod(method, options, imports, indent) {
1889
843
  imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime");
1890
844
  let text = "";
1891
845
  if (method.docs.summary || method.docs.description) {
1892
- text += helpers.formatDocCommentWithPrefix(fixUpMethodName(method), method.docs);
846
+ text += helpers.formatDocCommentWithPrefix(helpers.fixUpMethodName(method), method.docs);
1893
847
  text += genRespErrorDoc(method);
1894
848
  }
1895
- const zeroResp = getZeroReturnValue(method, "lro");
849
+ const zeroResp = getZeroReturnValue(method);
1896
850
  const methodParams = helpers.getMethodParameters(method);
1897
851
  for (const param of methodParams) {
1898
852
  text += helpers.formatCommentAsBulletItem(param.name, param.docs);
1899
853
  }
1900
- text += `func ${getClientReceiverDefinition(method.receiver)} ${fixUpMethodName(method)}(${params}) (${returns.join(", ")}) {\n`;
854
+ text += `func ${helpers.getClientReceiverDefinition(method.receiver)} ${helpers.fixUpMethodName(method)}(${params}) (${returns.join(", ")}) {\n`;
1901
855
  let pollerType = "nil";
1902
856
  let pollerTypeParam = `[${method.returns.name}]`;
1903
857
  if (method.kind === "lroPageableMethod") {
@@ -1999,25 +953,4 @@ function generateLROBeginMethod(method, options, imports, indent) {
1999
953
  text += "}\n\n";
2000
954
  return text;
2001
955
  }
2002
- export function fixUpMethodName(method) {
2003
- switch (method.kind) {
2004
- case "lroMethod":
2005
- case "lroPageableMethod":
2006
- return `Begin${method.name}`;
2007
- case "pageableMethod": {
2008
- let N = "N";
2009
- let name = method.name;
2010
- if (method.name[0] !== method.name[0].toUpperCase()) {
2011
- // the method isn't exported; don't export the pager ctor
2012
- N = "n";
2013
- // ensure correct casing of the emitted function name e.g.,
2014
- // "listThings" -> "newListThingsPager"
2015
- name = name[0].toUpperCase() + name.substring(1);
2016
- }
2017
- return `${N}ew${name}Pager`;
2018
- }
2019
- case "method":
2020
- return method.name;
2021
- }
2022
- }
2023
956
  //# sourceMappingURL=operations.js.map