@azure-tools/typespec-go 0.14.3 → 0.15.0-dev.4
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.
- package/CHANGELOG.md +669 -0
- package/README.md +6 -4
- package/dist/{codegen.go/src/core/clientFactory.d.ts → src/codegen/core/client-factory.d.ts} +2 -2
- package/dist/src/codegen/core/client-factory.d.ts.map +1 -0
- package/dist/{codegen.go/src/core/clientFactory.js → src/codegen/core/client-factory.js} +29 -24
- package/dist/src/codegen/core/client-factory.js.map +1 -0
- package/dist/{codegen.go/src/core/cloudConfig.d.ts → src/codegen/core/cloud-config.d.ts} +2 -2
- package/dist/src/codegen/core/cloud-config.d.ts.map +1 -0
- package/dist/{codegen.go/src/core/cloudConfig.js → src/codegen/core/cloud-config.js} +10 -9
- package/dist/src/codegen/core/cloud-config.js.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/constants.d.ts +1 -1
- package/dist/src/codegen/core/constants.d.ts.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/constants.js +9 -9
- package/dist/src/codegen/core/constants.js.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/errors.d.ts +1 -1
- package/dist/src/codegen/core/errors.d.ts.map +1 -0
- package/dist/src/codegen/core/errors.js.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/example.d.ts +1 -1
- package/dist/src/codegen/core/example.d.ts.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/example.js +155 -140
- package/dist/src/codegen/core/example.js.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/gomod.d.ts +1 -1
- package/dist/src/codegen/core/gomod.d.ts.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/gomod.js +8 -8
- package/dist/src/codegen/core/gomod.js.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/helpers.d.ts +5 -5
- package/dist/src/codegen/core/helpers.d.ts.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/helpers.js +308 -284
- package/dist/src/codegen/core/helpers.js.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/imports.d.ts +1 -1
- package/dist/src/codegen/core/imports.d.ts.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/imports.js +19 -18
- package/dist/src/codegen/core/imports.js.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/interfaces.d.ts +1 -1
- package/dist/src/codegen/core/interfaces.d.ts.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/interfaces.js +5 -5
- package/dist/src/codegen/core/interfaces.js.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/license.d.ts +1 -1
- package/dist/src/codegen/core/license.d.ts.map +1 -0
- package/dist/src/codegen/core/license.js.map +1 -0
- package/dist/src/codegen/core/metadata.d.ts +3 -0
- package/dist/src/codegen/core/metadata.d.ts.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/metadata.js +1 -1
- package/dist/src/codegen/core/metadata.js.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/models.d.ts +2 -2
- package/dist/src/codegen/core/models.d.ts.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/models.js +212 -181
- package/dist/src/codegen/core/models.js.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/operations.d.ts +1 -1
- package/dist/src/codegen/core/operations.d.ts.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/operations.js +383 -360
- package/dist/src/codegen/core/operations.js.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/options.d.ts +1 -1
- package/dist/src/codegen/core/options.d.ts.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/options.js +11 -11
- package/dist/src/codegen/core/options.js.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/polymorphics.d.ts +1 -1
- package/dist/src/codegen/core/polymorphics.d.ts.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/polymorphics.js +30 -30
- package/dist/src/codegen/core/polymorphics.js.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/responses.d.ts +1 -1
- package/dist/src/codegen/core/responses.d.ts.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/responses.js +28 -28
- package/dist/src/codegen/core/responses.js.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/version.d.ts +1 -1
- package/dist/src/codegen/core/version.d.ts.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/core/version.js +4 -4
- package/dist/src/codegen/core/version.js.map +1 -0
- package/dist/{codegen.go/src/core/xmlAdditionalProps.d.ts → src/codegen/core/xml-additional-props.d.ts} +2 -2
- package/dist/src/codegen/core/xml-additional-props.d.ts.map +1 -0
- package/dist/{codegen.go/src/core/xmlAdditionalProps.js → src/codegen/core/xml-additional-props.js} +11 -11
- package/dist/src/codegen/core/xml-additional-props.js.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/emitter.d.ts +2 -2
- package/dist/src/codegen/emitter.d.ts.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/emitter.js +58 -54
- package/dist/src/codegen/emitter.js.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/fake/factory.d.ts +1 -1
- package/dist/src/codegen/fake/factory.d.ts.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/fake/factory.js +22 -21
- package/dist/src/codegen/fake/factory.js.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/fake/internal.d.ts +1 -1
- package/dist/src/codegen/fake/internal.d.ts.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/fake/internal.js +13 -13
- package/dist/src/codegen/fake/internal.js.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/fake/servers.d.ts +1 -1
- package/dist/src/codegen/fake/servers.d.ts.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/fake/servers.js +332 -300
- package/dist/src/codegen/fake/servers.js.map +1 -0
- package/dist/src/codegen/index.d.ts +4 -0
- package/dist/src/codegen/index.d.ts.map +1 -0
- package/dist/{codegen.go/src → src/codegen}/index.js +3 -3
- package/dist/src/codegen/index.js.map +1 -0
- package/dist/{codemodel.go/src → src/codemodel}/client.d.ts +25 -25
- package/dist/src/codemodel/client.d.ts.map +1 -0
- package/dist/{codemodel.go/src → src/codemodel}/client.js +32 -32
- package/dist/src/codemodel/client.js.map +1 -0
- package/dist/{codemodel.go/src/codeModel.d.ts → src/codemodel/code-model.d.ts} +3 -3
- package/dist/src/codemodel/code-model.d.ts.map +1 -0
- package/dist/{codemodel.go/src/codeModel.js → src/codemodel/code-model.js} +1 -1
- package/dist/src/codemodel/code-model.js.map +1 -0
- package/dist/{codemodel.go/src → src/codemodel}/errors.d.ts +5 -5
- package/dist/src/codemodel/errors.d.ts.map +1 -0
- package/dist/{codemodel.go/src → src/codemodel}/errors.js +1 -1
- package/dist/src/codemodel/errors.js.map +1 -0
- package/dist/{codemodel.go/src → src/codemodel}/examples.d.ts +13 -13
- package/dist/src/codemodel/examples.d.ts.map +1 -0
- package/dist/{codemodel.go/src → src/codemodel}/examples.js +10 -10
- package/dist/src/codemodel/examples.js.map +1 -0
- package/dist/src/codemodel/index.d.ts +9 -0
- package/dist/src/codemodel/index.d.ts.map +1 -0
- package/dist/{codemodel.go/src → src/codemodel}/index.js +8 -8
- package/dist/src/codemodel/index.js.map +1 -0
- package/dist/{codemodel.go/src → src/codemodel}/method.d.ts +1 -1
- package/dist/src/codemodel/method.d.ts.map +1 -0
- package/dist/src/codemodel/method.js.map +1 -0
- package/dist/{codemodel.go/src → src/codemodel}/module.d.ts +8 -8
- package/dist/src/codemodel/module.d.ts.map +1 -0
- package/dist/{codemodel.go/src → src/codemodel}/module.js +12 -11
- package/dist/src/codemodel/module.js.map +1 -0
- package/dist/{codemodel.go/src → src/codemodel}/param.d.ts +26 -26
- package/dist/src/codemodel/param.d.ts.map +1 -0
- package/dist/{codemodel.go/src → src/codemodel}/param.js +56 -53
- package/dist/src/codemodel/param.js.map +1 -0
- package/dist/{codemodel.go/src → src/codemodel}/result.d.ts +15 -15
- package/dist/src/codemodel/result.d.ts.map +1 -0
- package/dist/{codemodel.go/src → src/codemodel}/result.js +27 -27
- package/dist/src/codemodel/result.js.map +1 -0
- package/dist/{codemodel.go/src → src/codemodel}/type.d.ts +30 -30
- package/dist/src/codemodel/type.d.ts.map +1 -0
- package/dist/{codemodel.go/src → src/codemodel}/type.js +77 -76
- package/dist/src/codemodel/type.js.map +1 -0
- package/dist/{typespec-go/src → src}/emitter.d.ts +2 -3
- package/dist/src/emitter.d.ts.map +1 -0
- package/dist/{typespec-go/src → src}/emitter.js +56 -45
- package/dist/src/emitter.js.map +1 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/{typespec-go/src → src}/index.js +2 -2
- package/dist/src/index.js.map +1 -0
- package/dist/{typespec-go/src → src}/lib.d.ts +16 -16
- package/dist/src/lib.d.ts.map +1 -0
- package/dist/{typespec-go/src → src}/lib.js +60 -61
- package/dist/src/lib.js.map +1 -0
- package/dist/src/naming/index.d.ts +3 -0
- package/dist/src/naming/index.d.ts.map +1 -0
- package/dist/{naming.go/src → src/naming}/index.js +2 -2
- package/dist/src/naming/index.js.map +1 -0
- package/dist/src/naming/mappings.d.ts.map +1 -0
- package/dist/src/naming/mappings.js +294 -0
- package/dist/src/naming/mappings.js.map +1 -0
- package/dist/src/naming/naming.d.ts.map +1 -0
- package/dist/{naming.go/src → src/naming}/naming.js +10 -10
- package/dist/src/naming/naming.js.map +1 -0
- package/dist/{typespec-go/src → src}/tcgcadapter/adapter.d.ts +3 -3
- package/dist/src/tcgcadapter/adapter.d.ts.map +1 -0
- package/dist/{typespec-go/src → src}/tcgcadapter/adapter.js +35 -31
- package/dist/src/tcgcadapter/adapter.js.map +1 -0
- package/dist/{typespec-go/src → src}/tcgcadapter/clients.d.ts +1 -1
- package/dist/src/tcgcadapter/clients.d.ts.map +1 -0
- package/dist/{typespec-go/src → src}/tcgcadapter/clients.js +360 -310
- package/dist/src/tcgcadapter/clients.js.map +1 -0
- package/dist/{typespec-go/src → src}/tcgcadapter/errors.d.ts +2 -2
- package/dist/src/tcgcadapter/errors.d.ts.map +1 -0
- package/dist/{typespec-go/src → src}/tcgcadapter/errors.js +1 -1
- package/dist/src/tcgcadapter/errors.js.map +1 -0
- package/dist/{typespec-go/src → src}/tcgcadapter/helpers.d.ts +3 -3
- package/dist/src/tcgcadapter/helpers.d.ts.map +1 -0
- package/dist/{typespec-go/src → src}/tcgcadapter/helpers.js +41 -30
- package/dist/src/tcgcadapter/helpers.js.map +1 -0
- package/dist/{typespec-go/src → src}/tcgcadapter/metadata.d.ts +2 -2
- package/dist/src/tcgcadapter/metadata.d.ts.map +1 -0
- package/dist/src/tcgcadapter/metadata.js +47 -0
- package/dist/src/tcgcadapter/metadata.js.map +1 -0
- package/dist/{typespec-go/src → src}/tcgcadapter/types.d.ts +2 -2
- package/dist/src/tcgcadapter/types.d.ts.map +1 -0
- package/dist/{typespec-go/src → src}/tcgcadapter/types.js +208 -191
- package/dist/src/tcgcadapter/types.js.map +1 -0
- package/package.json +77 -62
- package/dist/codegen.go/src/core/clientFactory.d.ts.map +0 -1
- package/dist/codegen.go/src/core/clientFactory.js.map +0 -1
- package/dist/codegen.go/src/core/cloudConfig.d.ts.map +0 -1
- package/dist/codegen.go/src/core/cloudConfig.js.map +0 -1
- package/dist/codegen.go/src/core/constants.d.ts.map +0 -1
- package/dist/codegen.go/src/core/constants.js.map +0 -1
- package/dist/codegen.go/src/core/errors.d.ts.map +0 -1
- package/dist/codegen.go/src/core/errors.js.map +0 -1
- package/dist/codegen.go/src/core/example.d.ts.map +0 -1
- package/dist/codegen.go/src/core/example.js.map +0 -1
- package/dist/codegen.go/src/core/gomod.d.ts.map +0 -1
- package/dist/codegen.go/src/core/gomod.js.map +0 -1
- package/dist/codegen.go/src/core/helpers.d.ts.map +0 -1
- package/dist/codegen.go/src/core/helpers.js.map +0 -1
- package/dist/codegen.go/src/core/imports.d.ts.map +0 -1
- package/dist/codegen.go/src/core/imports.js.map +0 -1
- package/dist/codegen.go/src/core/interfaces.d.ts.map +0 -1
- package/dist/codegen.go/src/core/interfaces.js.map +0 -1
- package/dist/codegen.go/src/core/license.d.ts.map +0 -1
- package/dist/codegen.go/src/core/license.js.map +0 -1
- package/dist/codegen.go/src/core/metadata.d.ts +0 -3
- package/dist/codegen.go/src/core/metadata.d.ts.map +0 -1
- package/dist/codegen.go/src/core/metadata.js.map +0 -1
- package/dist/codegen.go/src/core/models.d.ts.map +0 -1
- package/dist/codegen.go/src/core/models.js.map +0 -1
- package/dist/codegen.go/src/core/operations.d.ts.map +0 -1
- package/dist/codegen.go/src/core/operations.js.map +0 -1
- package/dist/codegen.go/src/core/options.d.ts.map +0 -1
- package/dist/codegen.go/src/core/options.js.map +0 -1
- package/dist/codegen.go/src/core/polymorphics.d.ts.map +0 -1
- package/dist/codegen.go/src/core/polymorphics.js.map +0 -1
- package/dist/codegen.go/src/core/responses.d.ts.map +0 -1
- package/dist/codegen.go/src/core/responses.js.map +0 -1
- package/dist/codegen.go/src/core/version.d.ts.map +0 -1
- package/dist/codegen.go/src/core/version.js.map +0 -1
- package/dist/codegen.go/src/core/xmlAdditionalProps.d.ts.map +0 -1
- package/dist/codegen.go/src/core/xmlAdditionalProps.js.map +0 -1
- package/dist/codegen.go/src/emitter.d.ts.map +0 -1
- package/dist/codegen.go/src/emitter.js.map +0 -1
- package/dist/codegen.go/src/fake/factory.d.ts.map +0 -1
- package/dist/codegen.go/src/fake/factory.js.map +0 -1
- package/dist/codegen.go/src/fake/internal.d.ts.map +0 -1
- package/dist/codegen.go/src/fake/internal.js.map +0 -1
- package/dist/codegen.go/src/fake/servers.d.ts.map +0 -1
- package/dist/codegen.go/src/fake/servers.js.map +0 -1
- package/dist/codegen.go/src/index.d.ts +0 -4
- package/dist/codegen.go/src/index.d.ts.map +0 -1
- package/dist/codegen.go/src/index.js.map +0 -1
- package/dist/codemodel.go/src/client.d.ts.map +0 -1
- package/dist/codemodel.go/src/client.js.map +0 -1
- package/dist/codemodel.go/src/codeModel.d.ts.map +0 -1
- package/dist/codemodel.go/src/codeModel.js.map +0 -1
- package/dist/codemodel.go/src/errors.d.ts.map +0 -1
- package/dist/codemodel.go/src/errors.js.map +0 -1
- package/dist/codemodel.go/src/examples.d.ts.map +0 -1
- package/dist/codemodel.go/src/examples.js.map +0 -1
- package/dist/codemodel.go/src/index.d.ts +0 -9
- package/dist/codemodel.go/src/index.d.ts.map +0 -1
- package/dist/codemodel.go/src/index.js.map +0 -1
- package/dist/codemodel.go/src/method.d.ts.map +0 -1
- package/dist/codemodel.go/src/method.js.map +0 -1
- package/dist/codemodel.go/src/module.d.ts.map +0 -1
- package/dist/codemodel.go/src/module.js.map +0 -1
- package/dist/codemodel.go/src/param.d.ts.map +0 -1
- package/dist/codemodel.go/src/param.js.map +0 -1
- package/dist/codemodel.go/src/result.d.ts.map +0 -1
- package/dist/codemodel.go/src/result.js.map +0 -1
- package/dist/codemodel.go/src/type.d.ts.map +0 -1
- package/dist/codemodel.go/src/type.js.map +0 -1
- package/dist/naming.go/src/index.d.ts +0 -3
- package/dist/naming.go/src/index.d.ts.map +0 -1
- package/dist/naming.go/src/index.js.map +0 -1
- package/dist/naming.go/src/mappings.d.ts.map +0 -1
- package/dist/naming.go/src/mappings.js +0 -294
- package/dist/naming.go/src/mappings.js.map +0 -1
- package/dist/naming.go/src/naming.d.ts.map +0 -1
- package/dist/naming.go/src/naming.js.map +0 -1
- package/dist/typespec-go/src/emitter.d.ts.map +0 -1
- package/dist/typespec-go/src/emitter.js.map +0 -1
- package/dist/typespec-go/src/index.d.ts +0 -3
- package/dist/typespec-go/src/index.d.ts.map +0 -1
- package/dist/typespec-go/src/index.js.map +0 -1
- package/dist/typespec-go/src/lib.d.ts.map +0 -1
- package/dist/typespec-go/src/lib.js.map +0 -1
- package/dist/typespec-go/src/tcgcadapter/adapter.d.ts.map +0 -1
- package/dist/typespec-go/src/tcgcadapter/adapter.js.map +0 -1
- package/dist/typespec-go/src/tcgcadapter/clients.d.ts.map +0 -1
- package/dist/typespec-go/src/tcgcadapter/clients.js.map +0 -1
- package/dist/typespec-go/src/tcgcadapter/errors.d.ts.map +0 -1
- package/dist/typespec-go/src/tcgcadapter/errors.js.map +0 -1
- package/dist/typespec-go/src/tcgcadapter/helpers.d.ts.map +0 -1
- package/dist/typespec-go/src/tcgcadapter/helpers.js.map +0 -1
- package/dist/typespec-go/src/tcgcadapter/metadata.d.ts.map +0 -1
- package/dist/typespec-go/src/tcgcadapter/metadata.js +0 -21
- package/dist/typespec-go/src/tcgcadapter/metadata.js.map +0 -1
- package/dist/typespec-go/src/tcgcadapter/types.d.ts.map +0 -1
- package/dist/typespec-go/src/tcgcadapter/types.js.map +0 -1
- /package/dist/{codegen.go/src → src/codegen}/core/errors.js +0 -0
- /package/dist/{codegen.go/src → src/codegen}/core/license.js +0 -0
- /package/dist/{codemodel.go/src → src/codemodel}/method.js +0 -0
- /package/dist/{naming.go/src → src/naming}/mappings.d.ts +0 -0
- /package/dist/{naming.go/src → src/naming}/naming.d.ts +0 -0
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
|
-
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
import
|
|
5
|
+
/* eslint-disable @typescript-eslint/no-deprecated -- uses TCGC APIs marked deprecated (correspondingMethodParams). */
|
|
6
|
+
import * as tcgc from "@azure-tools/typespec-client-generator-core";
|
|
7
|
+
import { NoTarget } from "@typespec/compiler";
|
|
8
|
+
import * as go from "../codemodel/index.js";
|
|
9
|
+
import { capitalize, createOptionsTypeDescription, createResponseEnvelopeDescription, ensureNameCase, getEscapedReservedName, uncapitalize, } from "../naming/naming.js";
|
|
10
|
+
import { AdapterError } from "./errors.js";
|
|
11
|
+
import * as helpers from "./helpers.js";
|
|
11
12
|
/**
|
|
12
13
|
* used to convert tcgc clients and their methods to Go code model types
|
|
13
14
|
*/
|
|
@@ -30,8 +31,9 @@ export class ClientAdapter {
|
|
|
30
31
|
* this includes parameter groups/options types and response envelopes.
|
|
31
32
|
*/
|
|
32
33
|
adaptClients() {
|
|
33
|
-
if (this.ta.ctx.emitContext.options[
|
|
34
|
-
|
|
34
|
+
if (this.ta.ctx.emitContext.options["single-client"] &&
|
|
35
|
+
this.ta.ctx.sdkPackage.clients.length > 1) {
|
|
36
|
+
throw new AdapterError("InvalidArgument", "single-client cannot be enabled when there are multiple clients");
|
|
35
37
|
}
|
|
36
38
|
for (const sdkClient of this.ta.ctx.sdkPackage.clients) {
|
|
37
39
|
// start with instantiable clients and recursively work down
|
|
@@ -47,13 +49,14 @@ export class ClientAdapter {
|
|
|
47
49
|
}
|
|
48
50
|
}
|
|
49
51
|
recursiveAdaptClient(sdkClient, parent) {
|
|
50
|
-
if (sdkClient.methods.length === 0 &&
|
|
52
|
+
if (sdkClient.methods.length === 0 &&
|
|
53
|
+
(sdkClient.children === undefined || sdkClient.children.length === 0)) {
|
|
51
54
|
// skip generating empty clients
|
|
52
55
|
return undefined;
|
|
53
56
|
}
|
|
54
57
|
let clientName = helpers.getEffectiveName(sdkClient);
|
|
55
58
|
// to keep compat with existing ARM packages, don't use hierarchically named clients
|
|
56
|
-
if (parent && this.ta.codeModel.type !==
|
|
59
|
+
if (parent && this.ta.codeModel.type !== "azure-arm") {
|
|
57
60
|
// for hierarchical clients, the child client names are built
|
|
58
61
|
// from the parent client name. this is because tsp allows subclients
|
|
59
62
|
// with the same name. consider the following example.
|
|
@@ -104,26 +107,29 @@ export class ClientAdapter {
|
|
|
104
107
|
AuthTypes[AuthTypes["WithAuth"] = 2] = "WithAuth";
|
|
105
108
|
})(AuthTypes || (AuthTypes = {}));
|
|
106
109
|
let authType = AuthTypes.Default;
|
|
107
|
-
if (!this.ta.codeModel.options.omitConstructors &&
|
|
110
|
+
if (!this.ta.codeModel.options.omitConstructors &&
|
|
111
|
+
this.ta.codeModel.root.kind === "containingModule") {
|
|
108
112
|
// emit a diagnostic indicating that no ctors will be emitted due to containing-module.
|
|
109
113
|
this.ta.ctx.program.reportDiagnostic({
|
|
110
|
-
code:
|
|
111
|
-
severity:
|
|
112
|
-
message:
|
|
114
|
+
code: "UnsupportedConfiguration",
|
|
115
|
+
severity: "warning",
|
|
116
|
+
message: "cannot emit client constructors when containing-module is set",
|
|
113
117
|
target: sdkClient.__raw.type ?? NoTarget,
|
|
114
118
|
});
|
|
115
119
|
}
|
|
116
|
-
if ((this.ta.codeModel.options.omitConstructors ||
|
|
120
|
+
if ((this.ta.codeModel.options.omitConstructors ||
|
|
121
|
+
this.ta.codeModel.root.kind === "containingModule") &&
|
|
122
|
+
this.ta.codeModel.options.generateExamples) {
|
|
117
123
|
// emit a diagnostic indicating that no ctors will be emitted due to containing-module.
|
|
118
124
|
this.ta.ctx.program.reportDiagnostic({
|
|
119
|
-
code:
|
|
120
|
-
severity:
|
|
121
|
-
message:
|
|
125
|
+
code: "UnsupportedConfiguration",
|
|
126
|
+
severity: "warning",
|
|
127
|
+
message: "cannot emit examples when containing-module or omit-constructors is set",
|
|
122
128
|
target: sdkClient.__raw.type ?? NoTarget,
|
|
123
129
|
});
|
|
124
130
|
}
|
|
125
131
|
/**
|
|
126
|
-
* processes a
|
|
132
|
+
* processes a credential, potentially adding its supporting client constructor
|
|
127
133
|
*
|
|
128
134
|
* @param goClient the Go client for which to add the constructor
|
|
129
135
|
* @param constructable the constructable for the current Go client
|
|
@@ -132,16 +138,16 @@ export class ClientAdapter {
|
|
|
132
138
|
*/
|
|
133
139
|
const processCredential = (goClient, constructable, cred) => {
|
|
134
140
|
switch (cred.type) {
|
|
135
|
-
case
|
|
141
|
+
case "noAuth":
|
|
136
142
|
return AuthTypes.NoAuth;
|
|
137
|
-
case
|
|
143
|
+
case "oauth2": {
|
|
138
144
|
constructable.constructors.push(this.createTokenCredentialCtor(goClient, cred));
|
|
139
145
|
return AuthTypes.WithAuth;
|
|
140
146
|
}
|
|
141
147
|
default:
|
|
142
148
|
this.ta.ctx.program.reportDiagnostic({
|
|
143
|
-
code:
|
|
144
|
-
severity:
|
|
149
|
+
code: "UnsupportedAuthenticationScheme",
|
|
150
|
+
severity: "warning",
|
|
145
151
|
message: `unsupported authentication scheme ${cred.type} will be omitted`,
|
|
146
152
|
target: sdkClient.__raw.type ?? NoTarget,
|
|
147
153
|
});
|
|
@@ -151,7 +157,7 @@ export class ClientAdapter {
|
|
|
151
157
|
return AuthTypes.WithAuth;
|
|
152
158
|
}
|
|
153
159
|
};
|
|
154
|
-
if (this.ta.codeModel.type ===
|
|
160
|
+
if (this.ta.codeModel.type === "azure-arm") {
|
|
155
161
|
// to keep compat with pre-tsp codegen we
|
|
156
162
|
// treat all ARM clients as instantiable.
|
|
157
163
|
sdkClient.clientInitialization.initializedBy |= tcgc.InitializedByFlags.Individually;
|
|
@@ -163,20 +169,21 @@ export class ClientAdapter {
|
|
|
163
169
|
// an existing module. this is because the constructor(s) require
|
|
164
170
|
// the module name and version info, and we can't make any
|
|
165
171
|
// assumptions about the names/location.
|
|
166
|
-
if (!this.ta.codeModel.options.omitConstructors &&
|
|
172
|
+
if (!this.ta.codeModel.options.omitConstructors &&
|
|
173
|
+
this.ta.codeModel.root.kind !== "containingModule") {
|
|
167
174
|
constructable = new go.Constructable(go.newClientOptions(this.ta.getPkg(), this.ta.codeModel.type, clientName));
|
|
168
175
|
}
|
|
169
176
|
for (const param of sdkClient.clientInitialization.parameters) {
|
|
170
177
|
switch (param.kind) {
|
|
171
|
-
case
|
|
178
|
+
case "credential":
|
|
172
179
|
if (!constructable) {
|
|
173
180
|
continue;
|
|
174
181
|
}
|
|
175
182
|
switch (param.type.kind) {
|
|
176
|
-
case
|
|
183
|
+
case "credential":
|
|
177
184
|
authType |= processCredential(goClient, constructable, param.type.scheme);
|
|
178
185
|
break;
|
|
179
|
-
case
|
|
186
|
+
case "union": {
|
|
180
187
|
const variantKinds = new Array();
|
|
181
188
|
for (const variantType of param.type.variantTypes) {
|
|
182
189
|
variantKinds.push(variantType.scheme.type);
|
|
@@ -187,25 +194,25 @@ export class ClientAdapter {
|
|
|
187
194
|
}
|
|
188
195
|
// no supported credential types were specified
|
|
189
196
|
if (authType === AuthTypes.Default) {
|
|
190
|
-
throw new AdapterError(
|
|
197
|
+
throw new AdapterError("UnsupportedTsp", `credential scheme types ${variantKinds.join()} NYI`, param.__raw?.node);
|
|
191
198
|
}
|
|
192
199
|
continue;
|
|
193
200
|
}
|
|
194
201
|
}
|
|
195
202
|
break;
|
|
196
|
-
case
|
|
197
|
-
if (this.ta.codeModel.type ===
|
|
203
|
+
case "endpoint": {
|
|
204
|
+
if (this.ta.codeModel.type === "azure-arm") {
|
|
198
205
|
// for ARM, the endpoint is handled via the azcore/arm.Client
|
|
199
206
|
// so we don't need to adapt it.
|
|
200
207
|
continue;
|
|
201
208
|
}
|
|
202
209
|
let endpointType;
|
|
203
210
|
switch (param.type.kind) {
|
|
204
|
-
case
|
|
211
|
+
case "endpoint":
|
|
205
212
|
// single endpoint without any supplemental path
|
|
206
213
|
endpointType = param.type;
|
|
207
214
|
break;
|
|
208
|
-
case
|
|
215
|
+
case "union":
|
|
209
216
|
// this is a union of endpoints. the first is the endpoint plus
|
|
210
217
|
// the supplemental path. the second is a "raw" endpoint which
|
|
211
218
|
// requires the caller to provide the complete endpoint. we only
|
|
@@ -233,7 +240,7 @@ export class ClientAdapter {
|
|
|
233
240
|
// there's either a suffix on the endpoint param, more template arguments, or both.
|
|
234
241
|
// either way we need to create supplemental info on the constructable.
|
|
235
242
|
// strip off the first segment which corresponds to the endpoint param as it's not needed.
|
|
236
|
-
const serverUrl = endpointType.serverUrl.replace(`{${templateArg.serializedName}}/`,
|
|
243
|
+
const serverUrl = endpointType.serverUrl.replace(`{${templateArg.serializedName}}/`, "");
|
|
237
244
|
constructable.endpoint.supplemental = new go.SupplementalEndpoint(serverUrl);
|
|
238
245
|
}
|
|
239
246
|
continue;
|
|
@@ -245,18 +252,18 @@ export class ClientAdapter {
|
|
|
245
252
|
adaptedParam.isApiVersion = templateArg.isApiVersionParam;
|
|
246
253
|
constructable.endpoint?.supplemental?.parameters.push(adaptedParam);
|
|
247
254
|
if (!go.isRequiredParameter(adaptedParam.style)) {
|
|
248
|
-
if (constructable.options.kind ===
|
|
255
|
+
if (constructable.options.kind === "clientOptions") {
|
|
249
256
|
constructable.options.parameters.push(adaptedParam);
|
|
250
257
|
}
|
|
251
258
|
else {
|
|
252
|
-
throw new AdapterError(
|
|
259
|
+
throw new AdapterError("UnsupportedTsp", "optional client parameters for ARM is not supported", templateArg.__raw?.node);
|
|
253
260
|
}
|
|
254
261
|
}
|
|
255
262
|
}
|
|
256
263
|
}
|
|
257
264
|
break;
|
|
258
265
|
}
|
|
259
|
-
case
|
|
266
|
+
case "method":
|
|
260
267
|
// some client params, notably api-version, can be explicitly
|
|
261
268
|
// defined in the operation signature:
|
|
262
269
|
// e.g. op withQueryApiVersion(@query("api-version") apiVersion: string)
|
|
@@ -288,7 +295,7 @@ export class ClientAdapter {
|
|
|
288
295
|
// this is a sub-client. it will share the client/host params of the parent.
|
|
289
296
|
// NOTE: we must propagate parent params before a potential recursive call
|
|
290
297
|
// to create a child client that will need to inherit our client params.
|
|
291
|
-
if (parent.instance?.kind ===
|
|
298
|
+
if (parent.instance?.kind === "templatedHost") {
|
|
292
299
|
goClient.instance = parent.instance;
|
|
293
300
|
}
|
|
294
301
|
// make a copy of the client params. this is to prevent
|
|
@@ -297,14 +304,14 @@ export class ClientAdapter {
|
|
|
297
304
|
goClient.parameters = new Array(...parent.parameters);
|
|
298
305
|
}
|
|
299
306
|
else {
|
|
300
|
-
throw new AdapterError(
|
|
307
|
+
throw new AdapterError("InternalError", `uninstantiable client ${sdkClient.name} has no parent`);
|
|
301
308
|
}
|
|
302
309
|
if (sdkClient.children && sdkClient.children.length > 0) {
|
|
303
310
|
for (const child of sdkClient.children) {
|
|
304
311
|
const subClient = this.recursiveAdaptClient(child, goClient);
|
|
305
312
|
// for ARM we skip adding client accessors as we use a customized
|
|
306
313
|
// client factory instead of hierarchical clients.
|
|
307
|
-
if (subClient && this.ta.codeModel.type !==
|
|
314
|
+
if (subClient && this.ta.codeModel.type !== "azure-arm") {
|
|
308
315
|
this.adaptClientAccessor(sdkClient, child, goClient, subClient);
|
|
309
316
|
}
|
|
310
317
|
}
|
|
@@ -312,7 +319,9 @@ export class ClientAdapter {
|
|
|
312
319
|
for (const sdkMethod of sdkClient.methods) {
|
|
313
320
|
this.adaptMethod(sdkMethod, goClient);
|
|
314
321
|
}
|
|
315
|
-
if (this.ta.codeModel.type ===
|
|
322
|
+
if (this.ta.codeModel.type === "azure-arm" &&
|
|
323
|
+
goClient.clientAccessors.length === 0 &&
|
|
324
|
+
goClient.methods.length === 0) {
|
|
316
325
|
// this is the service client. to keep compat with existing
|
|
317
326
|
// ARM SDKs we skip adding it to the code model in favor of
|
|
318
327
|
// the synthesized client factory.
|
|
@@ -331,16 +340,16 @@ export class ClientAdapter {
|
|
|
331
340
|
*/
|
|
332
341
|
createTokenCredentialCtor(goClient, cred) {
|
|
333
342
|
if (cred.flows.length === 0) {
|
|
334
|
-
throw new AdapterError(
|
|
343
|
+
throw new AdapterError("InternalError", `no flows defined for credential type ${cred.type}`, cred.model);
|
|
335
344
|
}
|
|
336
345
|
else if (cred.flows[0].scopes.length === 0) {
|
|
337
|
-
throw new AdapterError(
|
|
346
|
+
throw new AdapterError("InternalError", `no scopes defined for credential type ${cred.type}`, cred.model);
|
|
338
347
|
}
|
|
339
348
|
else if (cred.flows[0].scopes.length > 1) {
|
|
340
|
-
throw new AdapterError(
|
|
349
|
+
throw new AdapterError("InternalError", `too many scopes defined for credential type ${cred.type}`, cred.model);
|
|
341
350
|
}
|
|
342
351
|
const ctor = new go.Constructor(this.ta.getPkg(), `New${goClient.name}`);
|
|
343
|
-
ctor.parameters.push(new go.ClientCredentialParameter(
|
|
352
|
+
ctor.parameters.push(new go.ClientCredentialParameter("credential", new go.TokenCredential(cred.flows[0].scopes.map((each) => each.value))));
|
|
344
353
|
return ctor;
|
|
345
354
|
}
|
|
346
355
|
/**
|
|
@@ -368,7 +377,7 @@ export class ClientAdapter {
|
|
|
368
377
|
if (existsOnParent) {
|
|
369
378
|
continue;
|
|
370
379
|
}
|
|
371
|
-
const adaptedParam = new go.Parameter(getEscapedReservedName(helpers.getEffectiveName(param, true),
|
|
380
|
+
const adaptedParam = new go.Parameter(getEscapedReservedName(helpers.getEffectiveName(param, true), "Param"), this.ta.getWireType(param.type, true, true), true);
|
|
372
381
|
adaptedParam.docs.summary = param.summary;
|
|
373
382
|
adaptedParam.docs.description = param.doc;
|
|
374
383
|
clientAccessor.parameters.push(adaptedParam);
|
|
@@ -391,23 +400,23 @@ export class ClientAdapter {
|
|
|
391
400
|
paramType = this.ta.getWireType(sdkParam.type, true, false);
|
|
392
401
|
}
|
|
393
402
|
if (go.isURIParameterType(paramType)) {
|
|
394
|
-
const style = forceRequired ?
|
|
395
|
-
if (this.ta.codeModel.type ===
|
|
396
|
-
throw new AdapterError(
|
|
403
|
+
const style = forceRequired ? "required" : this.adaptParameterStyle(sdkParam);
|
|
404
|
+
if (this.ta.codeModel.type === "azure-arm" && !go.isRequiredParameter(style)) {
|
|
405
|
+
throw new AdapterError("UnsupportedTsp", "optional client parameters for ARM is not supported", sdkParam.__raw?.node);
|
|
397
406
|
}
|
|
398
|
-
const uriParam = new go.URIParameter(sdkParam.name, sdkParam.serializedName, paramType, style, helpers.isTypePassedByValue(sdkParam.type) || !sdkParam.optional,
|
|
407
|
+
const uriParam = new go.URIParameter(sdkParam.name, sdkParam.serializedName, paramType, style, helpers.isTypePassedByValue(sdkParam.type) || !sdkParam.optional, "client");
|
|
399
408
|
uriParam.docs.summary = sdkParam.summary;
|
|
400
409
|
uriParam.docs.description = sdkParam.doc;
|
|
401
410
|
uriParam.isApiVersion = sdkParam.isApiVersionParam;
|
|
402
411
|
return uriParam;
|
|
403
412
|
}
|
|
404
|
-
throw new AdapterError(
|
|
413
|
+
throw new AdapterError("UnsupportedTsp", `unsupported URI parameter type ${paramType.kind}`, sdkParam.__raw?.node);
|
|
405
414
|
}
|
|
406
415
|
adaptMethod(sdkMethod, goClient) {
|
|
407
416
|
const opName = helpers.getEffectiveName(sdkMethod, true);
|
|
408
|
-
const createReqName = helpers.getEffectiveName(sdkMethod, true,
|
|
409
|
-
const handleRespName = helpers.getEffectiveName(sdkMethod, true,
|
|
410
|
-
const naming = new go.MethodNaming(getEscapedReservedName(opName,
|
|
417
|
+
const createReqName = helpers.getEffectiveName(sdkMethod, true, "CreateRequest");
|
|
418
|
+
const handleRespName = helpers.getEffectiveName(sdkMethod, true, "HandleResponse");
|
|
419
|
+
const naming = new go.MethodNaming(getEscapedReservedName(opName, "Operation"), createReqName, handleRespName);
|
|
411
420
|
const getStatusCodes = function (httpOp) {
|
|
412
421
|
const statusCodes = new Array();
|
|
413
422
|
for (const response of httpOp.responses) {
|
|
@@ -424,38 +433,38 @@ export class ClientAdapter {
|
|
|
424
433
|
return statusCodes;
|
|
425
434
|
};
|
|
426
435
|
let methodName = helpers.getEffectiveName(sdkMethod);
|
|
427
|
-
if (sdkMethod.access ===
|
|
436
|
+
if (sdkMethod.access === "internal") {
|
|
428
437
|
methodName = uncapitalize(methodName);
|
|
429
|
-
if (sdkMethod.kind ===
|
|
438
|
+
if (sdkMethod.kind === "basic") {
|
|
430
439
|
// we add internal to the extra list so we don't end up with a method named "internal"
|
|
431
440
|
// which will collide with an unexported field with the same name. we don't need to
|
|
432
441
|
// do this for pagers/pollers as those methods get extra naming.
|
|
433
|
-
methodName = getEscapedReservedName(methodName,
|
|
442
|
+
methodName = getEscapedReservedName(methodName, "Method", ["internal"]);
|
|
434
443
|
}
|
|
435
444
|
}
|
|
436
445
|
const setLROInfo = function (goMethod, sdkMethod) {
|
|
437
|
-
const lroOptions = helpers.hasDecorator(
|
|
446
|
+
const lroOptions = helpers.hasDecorator("@useFinalStateVia", sdkMethod.decorators);
|
|
438
447
|
if (lroOptions) {
|
|
439
|
-
goMethod.finalStateVia = lroOptions[
|
|
448
|
+
goMethod.finalStateVia = lroOptions["finalState"];
|
|
440
449
|
}
|
|
441
450
|
if (sdkMethod.lroMetadata.finalResponse?.resultSegments) {
|
|
442
|
-
// 'resultSegments' is designed for
|
|
451
|
+
// 'resultSegments' is designed for future extensibility, currently only has one segment
|
|
443
452
|
goMethod.operationLocationResultPath = sdkMethod.lroMetadata.finalResponse.resultSegments
|
|
444
453
|
.map((segment) => {
|
|
445
454
|
return segment.serializationOptions.json?.name;
|
|
446
455
|
})
|
|
447
|
-
.join(
|
|
456
|
+
.join(".");
|
|
448
457
|
}
|
|
449
458
|
};
|
|
450
459
|
const setPageableInfo = (goMethod, sdkMethod) => {
|
|
451
460
|
return (paramsMap, respHeadersMap) => {
|
|
452
461
|
if (sdkMethod.pagingMetadata.nextLinkVerb) {
|
|
453
462
|
switch (sdkMethod.pagingMetadata.nextLinkVerb) {
|
|
454
|
-
case
|
|
463
|
+
case "GET":
|
|
455
464
|
// we default to GET in the ctor for PageableMethod
|
|
456
465
|
break;
|
|
457
|
-
case
|
|
458
|
-
goMethod.nextLinkVerb =
|
|
466
|
+
case "POST":
|
|
467
|
+
goMethod.nextLinkVerb = "post";
|
|
459
468
|
break;
|
|
460
469
|
default:
|
|
461
470
|
sdkMethod.pagingMetadata.nextLinkVerb;
|
|
@@ -468,28 +477,29 @@ export class ClientAdapter {
|
|
|
468
477
|
let method;
|
|
469
478
|
let applyPageableInfo;
|
|
470
479
|
switch (sdkMethod.kind) {
|
|
471
|
-
case
|
|
480
|
+
case "basic":
|
|
472
481
|
method = new go.SyncMethod(methodName, goClient, sdkMethod.operation.path, sdkMethod.operation.verb, statusCodes, naming);
|
|
473
482
|
break;
|
|
474
|
-
case
|
|
475
|
-
if (sdkMethod.pagingMetadata.nextLinkReInjectedParametersSegments !== undefined &&
|
|
476
|
-
|
|
483
|
+
case "paging":
|
|
484
|
+
if (sdkMethod.pagingMetadata.nextLinkReInjectedParametersSegments !== undefined &&
|
|
485
|
+
sdkMethod.pagingMetadata.nextLinkReInjectedParametersSegments.length > 0) {
|
|
486
|
+
throw new AdapterError("UnsupportedTsp", `paging with re-injected parameters is not supported`, sdkMethod.__raw?.node);
|
|
477
487
|
}
|
|
478
488
|
method = new go.PageableMethod(methodName, goClient, sdkMethod.operation.path, sdkMethod.operation.verb, statusCodes, naming);
|
|
479
489
|
applyPageableInfo = setPageableInfo(method, sdkMethod);
|
|
480
490
|
break;
|
|
481
|
-
case
|
|
491
|
+
case "lro":
|
|
482
492
|
method = new go.LROMethod(methodName, goClient, sdkMethod.operation.path, sdkMethod.operation.verb, statusCodes, naming);
|
|
483
493
|
setLROInfo(method, sdkMethod);
|
|
484
494
|
break;
|
|
485
|
-
case
|
|
495
|
+
case "lropaging":
|
|
486
496
|
method = new go.LROPageableMethod(methodName, goClient, sdkMethod.operation.path, sdkMethod.operation.verb, statusCodes, naming);
|
|
487
497
|
setLROInfo(method, sdkMethod);
|
|
488
498
|
applyPageableInfo = setPageableInfo(method, sdkMethod);
|
|
489
499
|
break;
|
|
490
500
|
default:
|
|
491
501
|
sdkMethod;
|
|
492
|
-
throw new AdapterError(
|
|
502
|
+
throw new AdapterError("UnsupportedTsp", "unreachable");
|
|
493
503
|
}
|
|
494
504
|
method.docs.summary = sdkMethod.summary;
|
|
495
505
|
method.docs.description = sdkMethod.doc;
|
|
@@ -510,58 +520,59 @@ export class ClientAdapter {
|
|
|
510
520
|
// build the field path for the next link segments
|
|
511
521
|
const nextLinkPath = new Array();
|
|
512
522
|
for (const segment of segments) {
|
|
513
|
-
if (segment.kind !==
|
|
514
|
-
throw new AdapterError(
|
|
523
|
+
if (segment.kind !== "property") {
|
|
524
|
+
throw new AdapterError("InternalError", `unexpected kind ${segment.kind} for next link segment in operation ${sdkMethod.name}`, sdkMethod.__raw?.node);
|
|
515
525
|
}
|
|
516
526
|
const nextLinkField = this.ta.fieldsMap.get(segment);
|
|
517
527
|
if (!nextLinkField) {
|
|
518
528
|
// the most likely explanation for this is lack of reference equality
|
|
519
|
-
throw new AdapterError(
|
|
529
|
+
throw new AdapterError("InternalError", `missing next link field name ${segment.name} for operation ${sdkMethod.name}`, sdkMethod.__raw?.node);
|
|
520
530
|
}
|
|
521
531
|
nextLinkPath.push(nextLinkField);
|
|
522
532
|
}
|
|
523
533
|
return nextLinkPath;
|
|
524
534
|
};
|
|
525
535
|
if (sdkMethod.pagingMetadata.nextLinkOperation) {
|
|
526
|
-
throw new AdapterError(
|
|
536
|
+
throw new AdapterError("UnsupportedTsp", "next page operation NYI", sdkMethod.__raw?.node);
|
|
527
537
|
}
|
|
528
538
|
else if (sdkMethod.pagingMetadata.nextLinkSegments) {
|
|
529
539
|
return new go.PageableStrategyNextLink(buildNextLinkPath(sdkMethod.pagingMetadata.nextLinkSegments));
|
|
530
540
|
}
|
|
531
|
-
else if (sdkMethod.pagingMetadata.continuationTokenParameterSegments &&
|
|
541
|
+
else if (sdkMethod.pagingMetadata.continuationTokenParameterSegments &&
|
|
542
|
+
sdkMethod.pagingMetadata.continuationTokenResponseSegments) {
|
|
532
543
|
const tokenReq = sdkMethod.pagingMetadata.continuationTokenParameterSegments[0];
|
|
533
544
|
const tokenResp = sdkMethod.pagingMetadata.continuationTokenResponseSegments[0];
|
|
534
545
|
// find the continuation token parameter
|
|
535
546
|
let requestToken;
|
|
536
547
|
switch (tokenReq.kind) {
|
|
537
|
-
case
|
|
548
|
+
case "method": {
|
|
538
549
|
const tokenParam = paramsMap.get(tokenReq);
|
|
539
550
|
if (!tokenParam) {
|
|
540
|
-
throw new AdapterError(
|
|
551
|
+
throw new AdapterError("InternalError", `missing continuation token request parameter name ${tokenReq.name} for operation ${sdkMethod.name}`, sdkMethod.__raw?.node);
|
|
541
552
|
}
|
|
542
553
|
requestToken = tokenParam;
|
|
543
554
|
break;
|
|
544
555
|
}
|
|
545
556
|
default:
|
|
546
|
-
throw new AdapterError(
|
|
557
|
+
throw new AdapterError("InternalError", `unhandled continuationTokenParameterSegment kind ${tokenReq.kind}`, tokenReq.__raw?.node);
|
|
547
558
|
}
|
|
548
559
|
// find the continuation token response
|
|
549
560
|
let responseToken;
|
|
550
561
|
switch (tokenResp.kind) {
|
|
551
|
-
case
|
|
562
|
+
case "property": {
|
|
552
563
|
responseToken = new go.PageableStrategyNextLink(buildNextLinkPath(sdkMethod.pagingMetadata.continuationTokenResponseSegments));
|
|
553
564
|
break;
|
|
554
565
|
}
|
|
555
|
-
case
|
|
566
|
+
case "responseheader": {
|
|
556
567
|
const tokenHeader = respHeadersMap.get(tokenResp);
|
|
557
568
|
if (!tokenHeader) {
|
|
558
|
-
throw new AdapterError(
|
|
569
|
+
throw new AdapterError("InternalError", `missing continuation token response header name ${tokenResp.name} for operation ${sdkMethod.name}`, sdkMethod.__raw?.node);
|
|
559
570
|
}
|
|
560
571
|
responseToken = tokenHeader;
|
|
561
572
|
break;
|
|
562
573
|
}
|
|
563
574
|
default:
|
|
564
|
-
throw new AdapterError(
|
|
575
|
+
throw new AdapterError("InternalError", `missing continuation token`, sdkMethod.__raw?.node);
|
|
565
576
|
}
|
|
566
577
|
return new go.PageableStrategyContinuationToken(requestToken, responseToken);
|
|
567
578
|
}
|
|
@@ -569,30 +580,30 @@ export class ClientAdapter {
|
|
|
569
580
|
return undefined;
|
|
570
581
|
}
|
|
571
582
|
populateMethod(sdkMethod, method) {
|
|
572
|
-
if (method.kind ===
|
|
573
|
-
throw new AdapterError(
|
|
583
|
+
if (method.kind === "nextPageMethod") {
|
|
584
|
+
throw new AdapterError("UnsupportedTsp", `unsupported method kind ${sdkMethod.kind}`, sdkMethod.__raw?.node);
|
|
574
585
|
}
|
|
575
586
|
let prefix = method.receiver.type.name;
|
|
576
|
-
if (this.ta.ctx.emitContext.options[
|
|
577
|
-
prefix =
|
|
587
|
+
if (this.ta.ctx.emitContext.options["single-client"]) {
|
|
588
|
+
prefix = "";
|
|
578
589
|
}
|
|
579
590
|
if (go.isLROMethod(method)) {
|
|
580
|
-
prefix +=
|
|
591
|
+
prefix += "Begin";
|
|
581
592
|
}
|
|
582
593
|
let optionalParamsGroupName = `${prefix}${method.name}Options`;
|
|
583
|
-
if (sdkMethod.access ===
|
|
594
|
+
if (sdkMethod.access === "internal") {
|
|
584
595
|
optionalParamsGroupName = uncapitalize(optionalParamsGroupName);
|
|
585
596
|
}
|
|
586
|
-
let optsGroupName =
|
|
597
|
+
let optsGroupName = "options";
|
|
587
598
|
// if there's an existing required parameter with the name options then pick something else.
|
|
588
599
|
// optional params will be inside the options type, so they can never collide.
|
|
589
600
|
for (const param of sdkMethod.parameters) {
|
|
590
601
|
if (!param.optional && param.name === optsGroupName) {
|
|
591
|
-
optsGroupName =
|
|
602
|
+
optsGroupName = "opts";
|
|
592
603
|
break;
|
|
593
604
|
}
|
|
594
605
|
}
|
|
595
|
-
method.optionalParamsGroup = new go.ParameterGroup(this.ta.getPkg(), optsGroupName, optionalParamsGroupName, false,
|
|
606
|
+
method.optionalParamsGroup = new go.ParameterGroup(this.ta.getPkg(), optsGroupName, optionalParamsGroupName, false, "method");
|
|
596
607
|
method.optionalParamsGroup.docs.summary = createOptionsTypeDescription(optionalParamsGroupName, this.getMethodNameForDocComment(method));
|
|
597
608
|
const respInfo = this.adaptResponseEnvelope(sdkMethod, method);
|
|
598
609
|
method.returns = respInfo.respEnv;
|
|
@@ -600,8 +611,10 @@ export class ClientAdapter {
|
|
|
600
611
|
// check if the method takes a binary body with an explicit content-type param.
|
|
601
612
|
// if it does, then we need to fix up the body param to reference it. we must
|
|
602
613
|
// do this after adapting all of the method parameters.
|
|
603
|
-
const binaryBodyParam = method.parameters.find((param) => param.kind ===
|
|
604
|
-
const contentTypeParam = method.parameters.find((param) => param.kind ===
|
|
614
|
+
const binaryBodyParam = method.parameters.find((param) => param.kind === "bodyParam" && param.bodyFormat === "binary");
|
|
615
|
+
const contentTypeParam = method.parameters.find((param) => param.kind === "headerScalarParam" &&
|
|
616
|
+
param.headerName.match(/^content-type$/i) &&
|
|
617
|
+
param.style !== "literal");
|
|
605
618
|
if (binaryBodyParam && contentTypeParam) {
|
|
606
619
|
// note that when content-type is a param, the defaultContentType on
|
|
607
620
|
// the body param will be a '*/*' literal. we want to replace that
|
|
@@ -609,17 +622,19 @@ export class ClientAdapter {
|
|
|
609
622
|
// it as a client-side default.
|
|
610
623
|
const bodyParam = binaryBodyParam;
|
|
611
624
|
switch (contentTypeParam.style) {
|
|
612
|
-
case
|
|
625
|
+
case "optional":
|
|
613
626
|
// convert the literal to a client-side default
|
|
614
627
|
contentTypeParam.style = new go.ClientSideDefault(bodyParam.contentType);
|
|
615
628
|
bodyParam.contentType = new go.ParameterRef(contentTypeParam.name);
|
|
616
629
|
break;
|
|
617
|
-
case
|
|
630
|
+
case "required":
|
|
618
631
|
bodyParam.contentType = new go.ParameterRef(contentTypeParam.name);
|
|
619
632
|
break;
|
|
620
633
|
default: {
|
|
621
|
-
const style = go.isClientSideDefault(contentTypeParam.style)
|
|
622
|
-
|
|
634
|
+
const style = go.isClientSideDefault(contentTypeParam.style)
|
|
635
|
+
? "client-side default"
|
|
636
|
+
: contentTypeParam.style;
|
|
637
|
+
throw new AdapterError("UnsupportedTsp", `unexpected content-type style ${style}`, sdkMethod.__raw?.node);
|
|
623
638
|
}
|
|
624
639
|
}
|
|
625
640
|
}
|
|
@@ -637,7 +652,7 @@ export class ClientAdapter {
|
|
|
637
652
|
const paramMapping = new Map();
|
|
638
653
|
const pageableParamsMap = new Map();
|
|
639
654
|
let optionalGroup;
|
|
640
|
-
if (method.kind !==
|
|
655
|
+
if (method.kind !== "nextPageMethod") {
|
|
641
656
|
// NextPageMethods don't have optional params
|
|
642
657
|
optionalGroup = method.optionalParamsGroup;
|
|
643
658
|
if (go.isLROMethod(method)) {
|
|
@@ -666,7 +681,7 @@ export class ClientAdapter {
|
|
|
666
681
|
// operation param. each param corresponds to a field within the operation param.
|
|
667
682
|
const opParam = allOpParams.find((opParam) => {
|
|
668
683
|
return opParam.correspondingMethodParams.find((methodParam) => {
|
|
669
|
-
if (param.type.kind ===
|
|
684
|
+
if (param.type.kind === "model") {
|
|
670
685
|
for (const property of param.type.properties) {
|
|
671
686
|
if (property === methodParam) {
|
|
672
687
|
return true;
|
|
@@ -677,9 +692,11 @@ export class ClientAdapter {
|
|
|
677
692
|
});
|
|
678
693
|
});
|
|
679
694
|
if (!opParam) {
|
|
680
|
-
throw new AdapterError(
|
|
695
|
+
throw new AdapterError("InternalError", `didn't find operation parameter for method ${sdkMethod.name} parameter ${param.name}`, sdkMethod.__raw?.node);
|
|
681
696
|
}
|
|
682
|
-
if (opParam.kind ===
|
|
697
|
+
if (opParam.kind === "header" &&
|
|
698
|
+
opParam.serializedName.match(/^content-type$/i) &&
|
|
699
|
+
param.type.kind === "constant") {
|
|
683
700
|
// if the body param is optional, then the content-type param is also optional.
|
|
684
701
|
// for optional constants, this has the side effect of the param being treated like
|
|
685
702
|
// a flag which isn't what we want. so, we mark it as required. we ONLY do this
|
|
@@ -692,27 +709,32 @@ export class ClientAdapter {
|
|
|
692
709
|
let adaptedParam;
|
|
693
710
|
// for the @bodyRoot decorator opParam.type !== param.type which is obviously not a
|
|
694
711
|
// spread parameter. we also need to check the usage flag to disambiguate these cases.
|
|
695
|
-
if (opParam.kind ===
|
|
712
|
+
if (opParam.kind === "body" &&
|
|
713
|
+
opParam.type.kind === "model" &&
|
|
714
|
+
opParam.type !== param.type &&
|
|
715
|
+
opParam.type.usage & tcgc.UsageFlags.Spread) {
|
|
696
716
|
const paramStyle = this.adaptParameterStyle(param);
|
|
697
|
-
const paramName = getEscapedReservedName(helpers.getEffectiveName(param, paramStyle ===
|
|
717
|
+
const paramName = getEscapedReservedName(helpers.getEffectiveName(param, paramStyle === "required"), "Param");
|
|
698
718
|
// if the param is required then it's always passed by value
|
|
699
|
-
const byVal = go.isRequiredParameter(paramStyle)
|
|
719
|
+
const byVal = go.isRequiredParameter(paramStyle)
|
|
720
|
+
? true
|
|
721
|
+
: helpers.isTypePassedByValue(param.type);
|
|
700
722
|
const contentType = this.adaptContentType(opParam.defaultContentType);
|
|
701
723
|
const getSerializedNameFromProperty = function (property) {
|
|
702
|
-
if (contentType ===
|
|
724
|
+
if (contentType === "JSON") {
|
|
703
725
|
return property.serializationOptions.json?.name;
|
|
704
726
|
}
|
|
705
|
-
if (contentType ===
|
|
727
|
+
if (contentType === "XML") {
|
|
706
728
|
return property.serializationOptions.xml?.name;
|
|
707
729
|
}
|
|
708
|
-
if (contentType ===
|
|
730
|
+
if (contentType === "binary") {
|
|
709
731
|
return property.serializationOptions.multipart?.name;
|
|
710
732
|
}
|
|
711
733
|
return undefined;
|
|
712
734
|
};
|
|
713
735
|
switch (contentType) {
|
|
714
|
-
case
|
|
715
|
-
case
|
|
736
|
+
case "JSON":
|
|
737
|
+
case "XML": {
|
|
716
738
|
// find the corresponding field within the model param so we can get the serialized name
|
|
717
739
|
let serializedName;
|
|
718
740
|
for (const property of opParam.type.properties) {
|
|
@@ -722,12 +744,12 @@ export class ClientAdapter {
|
|
|
722
744
|
}
|
|
723
745
|
}
|
|
724
746
|
if (!serializedName) {
|
|
725
|
-
throw new AdapterError(
|
|
747
|
+
throw new AdapterError("InternalError", `didn't find body model property for spread parameter ${param.name}`, param.__raw?.node);
|
|
726
748
|
}
|
|
727
749
|
adaptedParam = new go.PartialBodyParameter(paramName, serializedName, contentType, this.ta.getWireType(param.type, true, true), paramStyle, byVal);
|
|
728
750
|
break;
|
|
729
751
|
}
|
|
730
|
-
case
|
|
752
|
+
case "binary":
|
|
731
753
|
if (isMultipartBodyType(opParam.type)) {
|
|
732
754
|
adaptedParam = this.adaptMultipartFormParameter(param.name, opParam.type, paramStyle, byVal);
|
|
733
755
|
}
|
|
@@ -737,10 +759,10 @@ export class ClientAdapter {
|
|
|
737
759
|
}
|
|
738
760
|
break;
|
|
739
761
|
default:
|
|
740
|
-
throw new AdapterError(
|
|
762
|
+
throw new AdapterError("UnsupportedTsp", `unsupported spread param content type ${contentType}`, opParam.__raw?.node);
|
|
741
763
|
}
|
|
742
764
|
}
|
|
743
|
-
else if (param.type.kind ===
|
|
765
|
+
else if (param.type.kind === "model" && opParam.kind !== "body") {
|
|
744
766
|
// Attempt to handle as a parameter group for non-body parameter
|
|
745
767
|
// TODO: Leverage body parameter as a part of parameter group
|
|
746
768
|
const modelProperties = param.type.properties;
|
|
@@ -783,15 +805,16 @@ export class ClientAdapter {
|
|
|
783
805
|
const adaptedPropertyParam = this.adaptMethodParameter(method, propertyOpParam);
|
|
784
806
|
adaptedPropertyParam.docs.summary = property.summary;
|
|
785
807
|
adaptedPropertyParam.docs.description = property.doc;
|
|
786
|
-
if (adaptedPropertyParam.style ===
|
|
808
|
+
if (adaptedPropertyParam.style === "required" ||
|
|
809
|
+
adaptedPropertyParam.style === "literal") {
|
|
787
810
|
// Required params stay in the named parameter group
|
|
788
811
|
// Create the param group if it doesn't exist yet
|
|
789
812
|
if (!paramGroup) {
|
|
790
813
|
const paramStyle = this.adaptParameterStyle(param);
|
|
791
814
|
const isRequired = go.isRequiredParameter(paramStyle);
|
|
792
|
-
const paramName = getEscapedReservedName(helpers.getEffectiveName(param, isRequired),
|
|
815
|
+
const paramName = getEscapedReservedName(helpers.getEffectiveName(param, isRequired), "Param");
|
|
793
816
|
paramGroup = new go.ParameterGroup(this.ta.getPkg(), paramName, paramGroupName, true, // param group with required params is always required
|
|
794
|
-
|
|
817
|
+
"method");
|
|
795
818
|
// Use docs from model if present, otherwise generate default description
|
|
796
819
|
if (param.type.summary || param.type.doc) {
|
|
797
820
|
paramGroup.docs.summary = param.type.summary;
|
|
@@ -812,7 +835,7 @@ export class ClientAdapter {
|
|
|
812
835
|
else {
|
|
813
836
|
// Optional params are moved to the method's options type
|
|
814
837
|
if (!optionalGroup) {
|
|
815
|
-
throw new AdapterError(
|
|
838
|
+
throw new AdapterError("InternalError", `optional parameter ${property.name} has no optional parameter group`, property.__raw?.node);
|
|
816
839
|
}
|
|
817
840
|
adaptedPropertyParam.group = optionalGroup;
|
|
818
841
|
addParameterToMethod(adaptedPropertyParam, propertyOpParam);
|
|
@@ -824,24 +847,26 @@ export class ClientAdapter {
|
|
|
824
847
|
}
|
|
825
848
|
else {
|
|
826
849
|
adaptedParam = this.adaptMethodParameter(method, opParam);
|
|
827
|
-
if (method.kind !==
|
|
850
|
+
if (method.kind !== "nextPageMethod" && go.isPageableMethod(method)) {
|
|
828
851
|
switch (adaptedParam.kind) {
|
|
829
|
-
case
|
|
830
|
-
case
|
|
852
|
+
case "headerScalarParam":
|
|
853
|
+
case "queryScalarParam":
|
|
831
854
|
pageableParamsMap.set(param, adaptedParam);
|
|
832
855
|
}
|
|
833
856
|
}
|
|
834
857
|
}
|
|
835
858
|
adaptedParam.docs.summary = param.summary;
|
|
836
859
|
adaptedParam.docs.description = param.doc;
|
|
837
|
-
if (go.isClientSideDefault(adaptedParam.style) &&
|
|
860
|
+
if (go.isClientSideDefault(adaptedParam.style) &&
|
|
861
|
+
!adaptedParam.docs.summary &&
|
|
862
|
+
!adaptedParam.docs.description) {
|
|
838
863
|
adaptedParam.docs.summary = helpers.getClientDefaultValueDoc(adaptedParam.style.defaultValue);
|
|
839
864
|
}
|
|
840
865
|
addParameterToMethod(adaptedParam, opParam);
|
|
841
|
-
if (adaptedParam.style !==
|
|
866
|
+
if (adaptedParam.style !== "required" && adaptedParam.style !== "literal") {
|
|
842
867
|
// add optional method param to the options param group
|
|
843
868
|
if (!optionalGroup) {
|
|
844
|
-
throw new AdapterError(
|
|
869
|
+
throw new AdapterError("InternalError", `optional parameter ${param.name} has no optional parameter group`, param.__raw?.node);
|
|
845
870
|
}
|
|
846
871
|
adaptedParam.group = optionalGroup;
|
|
847
872
|
optionalGroup.params.push(adaptedParam);
|
|
@@ -872,11 +897,13 @@ export class ClientAdapter {
|
|
|
872
897
|
if (!method.receiver.type.parameters.find((v) => {
|
|
873
898
|
return v.name === adaptedParam.name;
|
|
874
899
|
})) {
|
|
875
|
-
if (this.ta.codeModel.type ===
|
|
876
|
-
|
|
900
|
+
if (this.ta.codeModel.type === "azure-arm" &&
|
|
901
|
+
adaptedParam.style !== "literal" &&
|
|
902
|
+
adaptedParam.style !== "required") {
|
|
903
|
+
throw new AdapterError("UnsupportedTsp", "optional client parameters for ARM is not supported", opParam.__raw?.node);
|
|
877
904
|
}
|
|
878
905
|
method.receiver.type.parameters.push(adaptedParam);
|
|
879
|
-
if (method.receiver.type.instance?.kind ===
|
|
906
|
+
if (method.receiver.type.instance?.kind === "constructable") {
|
|
880
907
|
// if this is an instantiable client then also add
|
|
881
908
|
// the client parameter to all constructors
|
|
882
909
|
for (const ctor of method.receiver.type.instance.constructors) {
|
|
@@ -894,15 +921,15 @@ export class ClientAdapter {
|
|
|
894
921
|
adaptContentType(contentTypeStr) {
|
|
895
922
|
// we only recognize/support JSON, text, and XML content types, so assume anything else is binary
|
|
896
923
|
// NOTE: we check XML before text in order to support text/xml
|
|
897
|
-
let contentType =
|
|
924
|
+
let contentType = "binary";
|
|
898
925
|
if (contentTypeStr.match(/json/i)) {
|
|
899
|
-
contentType =
|
|
926
|
+
contentType = "JSON";
|
|
900
927
|
}
|
|
901
928
|
else if (contentTypeStr.match(/xml/i)) {
|
|
902
|
-
contentType =
|
|
929
|
+
contentType = "XML";
|
|
903
930
|
}
|
|
904
931
|
else if (contentTypeStr.match(/text/i)) {
|
|
905
|
-
contentType =
|
|
932
|
+
contentType = "Text";
|
|
906
933
|
}
|
|
907
934
|
return contentType;
|
|
908
935
|
}
|
|
@@ -929,31 +956,31 @@ export class ClientAdapter {
|
|
|
929
956
|
client.apiVersions.push(versionConst);
|
|
930
957
|
}
|
|
931
958
|
paramType = new go.Literal(versionConst, versionConst.name);
|
|
932
|
-
paramStyle =
|
|
959
|
+
paramStyle = "literal";
|
|
933
960
|
}
|
|
934
961
|
else {
|
|
935
962
|
paramType = this.ta.getStringType();
|
|
936
|
-
paramStyle = opParam.optional ?
|
|
963
|
+
paramStyle = opParam.optional ? "optional" : "required";
|
|
937
964
|
}
|
|
938
|
-
const paramLoc = opParam.onClient ?
|
|
965
|
+
const paramLoc = opParam.onClient ? "client" : "method";
|
|
939
966
|
let apiVersionParam;
|
|
940
967
|
switch (opParam.kind) {
|
|
941
|
-
case
|
|
942
|
-
apiVersionParam = new go.HeaderScalarParameter(
|
|
968
|
+
case "header":
|
|
969
|
+
apiVersionParam = new go.HeaderScalarParameter("apiVersion", opParam.serializedName, paramType, paramStyle, true, paramLoc);
|
|
943
970
|
break;
|
|
944
|
-
case
|
|
945
|
-
apiVersionParam = new go.PathScalarParameter(
|
|
971
|
+
case "path":
|
|
972
|
+
apiVersionParam = new go.PathScalarParameter("apiVersion", opParam.serializedName, true, paramType, paramStyle, true, paramLoc);
|
|
946
973
|
break;
|
|
947
|
-
case
|
|
948
|
-
apiVersionParam = new go.QueryScalarParameter(
|
|
974
|
+
case "query":
|
|
975
|
+
apiVersionParam = new go.QueryScalarParameter("apiVersion", opParam.serializedName, true, paramType, paramStyle, true, paramLoc);
|
|
949
976
|
break;
|
|
950
977
|
default:
|
|
951
|
-
throw new AdapterError(
|
|
978
|
+
throw new AdapterError("UnsupportedTsp", `unsupported API version param kind ${opParam.kind}`, opParam.__raw?.node);
|
|
952
979
|
}
|
|
953
980
|
apiVersionParam.isApiVersion = true;
|
|
954
981
|
return apiVersionParam;
|
|
955
982
|
}
|
|
956
|
-
let location =
|
|
983
|
+
let location = "method";
|
|
957
984
|
const getClientParamsKey = function (opParam) {
|
|
958
985
|
// include the param kind in the key name as a client param can be used
|
|
959
986
|
// in different places across methods (path/query)
|
|
@@ -967,7 +994,7 @@ export class ClientAdapter {
|
|
|
967
994
|
if (clientParam) {
|
|
968
995
|
return clientParam;
|
|
969
996
|
}
|
|
970
|
-
location =
|
|
997
|
+
location = "client";
|
|
971
998
|
}
|
|
972
999
|
// we use the operation param's corresponding method
|
|
973
1000
|
// param as the source of truth during adaptation.
|
|
@@ -977,78 +1004,85 @@ export class ClientAdapter {
|
|
|
977
1004
|
// this is only applicable to spread params
|
|
978
1005
|
// which should have been handled earlier.
|
|
979
1006
|
// so, if we get here, we have a bug elsewhere
|
|
980
|
-
throw new AdapterError(
|
|
1007
|
+
throw new AdapterError("InternalError", `unexpected correspondingMethodParams.length of ${opParam.correspondingMethodParams.length}`, opParam.__raw?.node);
|
|
981
1008
|
}
|
|
982
1009
|
const methodParam = opParam.correspondingMethodParams[0];
|
|
983
1010
|
let paramStyle = this.adaptParameterStyle(methodParam);
|
|
984
|
-
if (opParam.kind ===
|
|
1011
|
+
if (opParam.kind === "body") {
|
|
985
1012
|
const contentType = this.adaptContentType(opParam.defaultContentType);
|
|
986
1013
|
// only force modeled body params to be required (binary payloads can be optional)
|
|
987
|
-
if (contentType !==
|
|
988
|
-
|
|
1014
|
+
if (contentType !== "binary" &&
|
|
1015
|
+
(method.httpMethod === "patch" || method.httpMethod === "put")) {
|
|
1016
|
+
paramStyle = "required";
|
|
989
1017
|
}
|
|
990
1018
|
}
|
|
991
|
-
const paramName = getEscapedReservedName(helpers.getEffectiveName(methodParam, paramStyle ===
|
|
992
|
-
const byVal = go.isRequiredParameter(paramStyle)
|
|
1019
|
+
const paramName = getEscapedReservedName(helpers.getEffectiveName(methodParam, paramStyle === "required"), "Param");
|
|
1020
|
+
const byVal = go.isRequiredParameter(paramStyle)
|
|
1021
|
+
? true
|
|
1022
|
+
: helpers.isTypePassedByValue(methodParam.type);
|
|
993
1023
|
let adaptedParam;
|
|
994
1024
|
switch (opParam.kind) {
|
|
995
|
-
case
|
|
1025
|
+
case "body":
|
|
996
1026
|
if (isMultipartBodyType(opParam.type)) {
|
|
997
1027
|
adaptedParam = this.adaptMultipartFormParameter(methodParam.name, opParam.type, paramStyle, byVal);
|
|
998
1028
|
}
|
|
999
1029
|
else {
|
|
1000
1030
|
const contentType = this.adaptContentType(opParam.defaultContentType);
|
|
1001
1031
|
let bodyType = this.ta.getWireType(methodParam.type, false, true);
|
|
1002
|
-
if (contentType ===
|
|
1032
|
+
if (contentType === "binary") {
|
|
1003
1033
|
// tcgc models binary params as 'bytes' but we want an io.ReadSeekCloser
|
|
1004
|
-
bodyType = this.ta.getReadSeekCloser(methodParam.type.kind ===
|
|
1034
|
+
bodyType = this.ta.getReadSeekCloser(methodParam.type.kind === "array");
|
|
1005
1035
|
}
|
|
1006
1036
|
const contentTypeLiteral = this.ta.getLiteral(this.ta.getStringType(), opParam.defaultContentType);
|
|
1007
1037
|
adaptedParam = new go.BodyParameter(paramName, contentType, contentTypeLiteral, bodyType, paramStyle, byVal);
|
|
1008
|
-
if (contentType ===
|
|
1038
|
+
if (contentType === "XML" && methodParam.type.kind === "array") {
|
|
1009
1039
|
// this is for compat with autorest.go
|
|
1010
1040
|
adaptedParam.xml = new go.XMLInfo();
|
|
1011
1041
|
adaptedParam.xml.wrapper = methodParam.type.name;
|
|
1012
1042
|
}
|
|
1013
1043
|
}
|
|
1014
1044
|
break;
|
|
1015
|
-
case
|
|
1045
|
+
case "cookie":
|
|
1016
1046
|
// TODO: currently we don't have Azure service using cookie parameter. need to add support if needed in the future.
|
|
1017
|
-
throw new AdapterError(
|
|
1018
|
-
case
|
|
1019
|
-
if (opParam.serializedName ===
|
|
1047
|
+
throw new AdapterError("UnsupportedTsp", "unsupported parameter type cookie", opParam.__raw?.node);
|
|
1048
|
+
case "header":
|
|
1049
|
+
if (opParam.serializedName === "x-ms-meta") {
|
|
1020
1050
|
const type = this.ta.getWireType(methodParam.type, true, false);
|
|
1021
|
-
if (type.kind !==
|
|
1022
|
-
throw new AdapterError(
|
|
1051
|
+
if (type.kind !== "map") {
|
|
1052
|
+
throw new AdapterError("InternalError", `unexpected kind ${type.kind} for HeaderMapParameter ${methodParam.name}`, opParam.__raw?.node);
|
|
1023
1053
|
}
|
|
1024
1054
|
adaptedParam = new go.HeaderMapParameter(paramName, `${opParam.serializedName}-`, type, paramStyle, byVal, location);
|
|
1025
1055
|
}
|
|
1026
1056
|
else if (opParam.collectionFormat) {
|
|
1027
|
-
if (opParam.collectionFormat ===
|
|
1028
|
-
throw new AdapterError(
|
|
1057
|
+
if (opParam.collectionFormat === "multi" || opParam.collectionFormat === "form") {
|
|
1058
|
+
throw new AdapterError("InternalError", `unexpected collection format ${opParam.collectionFormat} for HeaderCollectionParameter`, opParam.__raw?.node);
|
|
1029
1059
|
}
|
|
1030
1060
|
// TODO: is hard-coded false for element type by value correct?
|
|
1031
1061
|
const type = this.ta.getWireType(methodParam.type, true, false);
|
|
1032
|
-
if (type.kind !==
|
|
1033
|
-
throw new AdapterError(
|
|
1062
|
+
if (type.kind !== "slice") {
|
|
1063
|
+
throw new AdapterError("InternalError", `unexpected kind ${type.kind} for HeaderCollectionParameter ${methodParam.name}`, opParam.__raw?.node);
|
|
1034
1064
|
}
|
|
1035
|
-
adaptedParam = new go.HeaderCollectionParameter(paramName, opParam.serializedName, type, opParam.collectionFormat ===
|
|
1065
|
+
adaptedParam = new go.HeaderCollectionParameter(paramName, opParam.serializedName, type, opParam.collectionFormat === "simple" ? "csv" : opParam.collectionFormat, paramStyle, byVal, location);
|
|
1036
1066
|
}
|
|
1037
1067
|
else {
|
|
1038
1068
|
adaptedParam = new go.HeaderScalarParameter(paramName, opParam.serializedName, this.adaptHeaderScalarType(methodParam.type, true), paramStyle, byVal, location);
|
|
1039
1069
|
}
|
|
1040
1070
|
break;
|
|
1041
|
-
case
|
|
1071
|
+
case "path":
|
|
1042
1072
|
adaptedParam = new go.PathScalarParameter(paramName, opParam.serializedName, !opParam.allowReserved, this.adaptPathScalarParameterType(methodParam.type), paramStyle, byVal, location);
|
|
1043
1073
|
break;
|
|
1044
|
-
case
|
|
1074
|
+
case "query":
|
|
1045
1075
|
if (opParam.collectionFormat) {
|
|
1046
1076
|
const type = this.ta.getWireType(methodParam.type, true, false);
|
|
1047
|
-
if (type.kind !==
|
|
1048
|
-
throw new AdapterError(
|
|
1077
|
+
if (type.kind !== "slice") {
|
|
1078
|
+
throw new AdapterError("InternalError", `unexpected kind ${type.kind} for QueryCollectionParameter ${methodParam.name}`, opParam.__raw?.node);
|
|
1049
1079
|
}
|
|
1050
1080
|
// TODO: unencoded query param
|
|
1051
|
-
adaptedParam = new go.QueryCollectionParameter(paramName, opParam.serializedName, true, type, opParam.collectionFormat ===
|
|
1081
|
+
adaptedParam = new go.QueryCollectionParameter(paramName, opParam.serializedName, true, type, opParam.collectionFormat === "simple"
|
|
1082
|
+
? "csv"
|
|
1083
|
+
: opParam.collectionFormat === "form"
|
|
1084
|
+
? "multi"
|
|
1085
|
+
: opParam.collectionFormat, paramStyle, byVal, location);
|
|
1052
1086
|
}
|
|
1053
1087
|
else {
|
|
1054
1088
|
// TODO: unencoded query param
|
|
@@ -1056,7 +1090,7 @@ export class ClientAdapter {
|
|
|
1056
1090
|
}
|
|
1057
1091
|
break;
|
|
1058
1092
|
}
|
|
1059
|
-
if (adaptedParam.location ===
|
|
1093
|
+
if (adaptedParam.location === "client") {
|
|
1060
1094
|
// track client parameter for later use
|
|
1061
1095
|
this.clientParams.set(getClientParamsKey(opParam), adaptedParam);
|
|
1062
1096
|
}
|
|
@@ -1076,7 +1110,7 @@ export class ClientAdapter {
|
|
|
1076
1110
|
// tcgc wraps inline multipart params in a generated model with a single property.
|
|
1077
1111
|
// unwrap to the inner property to get the actual param name and type.
|
|
1078
1112
|
if (paramType.properties.length !== 1) {
|
|
1079
|
-
throw new AdapterError(
|
|
1113
|
+
throw new AdapterError("InternalError", `unexpected number of properties: ${paramType.properties.length}`, paramType.__raw?.node);
|
|
1080
1114
|
}
|
|
1081
1115
|
const prop = paramType.properties[0];
|
|
1082
1116
|
paramName = prop.name;
|
|
@@ -1088,29 +1122,31 @@ export class ClientAdapter {
|
|
|
1088
1122
|
// only use MultipartContent for file parts with a fixed content type.
|
|
1089
1123
|
// non-file parts (e.g. HttpPart<{ @body body: float64; @header contentType: "text/plain" }>)
|
|
1090
1124
|
// should retain their underlying type (e.g. float64).
|
|
1091
|
-
if (multipartOptions?.isFilePart &&
|
|
1092
|
-
type
|
|
1125
|
+
if (multipartOptions?.isFilePart &&
|
|
1126
|
+
multipartOptions.contentType?.type.kind === "constant" &&
|
|
1127
|
+
multipartOptions.defaultContentTypes.length === 1) {
|
|
1128
|
+
type = this.ta.getMultipartContent(paramAsSdkType.kind === "array", multipartOptions.defaultContentTypes[0]);
|
|
1093
1129
|
}
|
|
1094
|
-
else if (paramAsSdkType.kind ===
|
|
1130
|
+
else if (paramAsSdkType.kind === "bytes" && paramAsSdkType.encode === "bytes") {
|
|
1095
1131
|
type = this.ta.getReadSeekCloser(false);
|
|
1096
1132
|
}
|
|
1097
1133
|
else {
|
|
1098
1134
|
type = this.ta.getWireType(paramAsSdkType, true, true);
|
|
1099
1135
|
}
|
|
1100
|
-
paramName = getEscapedReservedName(helpers.getEffectiveName({ name: paramName, isExactName }, paramStyle ===
|
|
1136
|
+
paramName = getEscapedReservedName(helpers.getEffectiveName({ name: paramName, isExactName }, paramStyle === "required"), "Param");
|
|
1101
1137
|
return new go.MultipartFormBodyParameter(paramName, type, paramStyle, byVal);
|
|
1102
1138
|
}
|
|
1103
1139
|
getMethodNameForDocComment(method) {
|
|
1104
1140
|
let methodName;
|
|
1105
1141
|
switch (method.kind) {
|
|
1106
|
-
case
|
|
1107
|
-
case
|
|
1142
|
+
case "lroMethod":
|
|
1143
|
+
case "lroPageableMethod":
|
|
1108
1144
|
methodName = `Begin${method.name}`;
|
|
1109
1145
|
break;
|
|
1110
|
-
case
|
|
1146
|
+
case "method":
|
|
1111
1147
|
methodName = method.name;
|
|
1112
1148
|
break;
|
|
1113
|
-
case
|
|
1149
|
+
case "pageableMethod":
|
|
1114
1150
|
methodName = `New${method.name}Pager`;
|
|
1115
1151
|
break;
|
|
1116
1152
|
}
|
|
@@ -1119,18 +1155,20 @@ export class ClientAdapter {
|
|
|
1119
1155
|
adaptResponseEnvelope(sdkMethod, method) {
|
|
1120
1156
|
// TODO: add Envelope suffix if name collides with existing type
|
|
1121
1157
|
let prefix = method.receiver.type.name;
|
|
1122
|
-
if (this.ta.ctx.emitContext.options[
|
|
1123
|
-
prefix =
|
|
1158
|
+
if (this.ta.ctx.emitContext.options["single-client"]) {
|
|
1159
|
+
prefix = "";
|
|
1124
1160
|
}
|
|
1125
1161
|
let respEnvName = `${prefix}${method.name}Response`;
|
|
1126
|
-
if (sdkMethod.access ===
|
|
1162
|
+
if (sdkMethod.access === "internal") {
|
|
1127
1163
|
respEnvName = uncapitalize(respEnvName);
|
|
1128
1164
|
}
|
|
1129
|
-
const customName = helpers.getClientOption(
|
|
1165
|
+
const customName = helpers.getClientOption("responseEnvelopeName", sdkMethod, this.ta.ctx.program);
|
|
1130
1166
|
if (customName) {
|
|
1131
1167
|
respEnvName = customName;
|
|
1132
1168
|
}
|
|
1133
|
-
const respEnv = new go.ResponseEnvelope(respEnvName, {
|
|
1169
|
+
const respEnv = new go.ResponseEnvelope(respEnvName, {
|
|
1170
|
+
summary: createResponseEnvelopeDescription(respEnvName, this.getMethodNameForDocComment(method)),
|
|
1171
|
+
}, method);
|
|
1134
1172
|
this.ta.getPkg().responseEnvelopes.push(respEnv);
|
|
1135
1173
|
const pageableRespHeadersMap = new Map();
|
|
1136
1174
|
// we defer adding a literal content-type header to the response envelope
|
|
@@ -1146,10 +1184,11 @@ export class ClientAdapter {
|
|
|
1146
1184
|
continue;
|
|
1147
1185
|
}
|
|
1148
1186
|
let headerResp;
|
|
1149
|
-
if (httpHeader.serializedName ===
|
|
1187
|
+
if (httpHeader.serializedName === "x-ms-meta" ||
|
|
1188
|
+
httpHeader.serializedName === "x-ms-or") {
|
|
1150
1189
|
const type = this.ta.getWireType(httpHeader.type, true, false);
|
|
1151
|
-
if (type.kind !==
|
|
1152
|
-
throw new AdapterError(
|
|
1190
|
+
if (type.kind !== "map") {
|
|
1191
|
+
throw new AdapterError("InternalError", `unexpected kind ${type.kind} for HeaderMapResponse ${httpHeader.name}`);
|
|
1153
1192
|
}
|
|
1154
1193
|
headerResp = new go.HeaderMapResponse(helpers.getEffectiveName(httpHeader), type, `${httpHeader.serializedName}-`);
|
|
1155
1194
|
}
|
|
@@ -1173,9 +1212,10 @@ export class ClientAdapter {
|
|
|
1173
1212
|
}
|
|
1174
1213
|
let sdkResponseType = sdkMethod.response.type;
|
|
1175
1214
|
// since HEAD requests don't return a type, we must check this before checking sdkResponseType
|
|
1176
|
-
if (method.httpMethod ===
|
|
1177
|
-
|
|
1178
|
-
respEnv.result
|
|
1215
|
+
if (method.httpMethod === "head" &&
|
|
1216
|
+
this.ta.ctx.emitContext.options["head-as-boolean"] === true) {
|
|
1217
|
+
respEnv.result = new go.HeadAsBooleanResult("Success");
|
|
1218
|
+
respEnv.result.docs.summary = "Success indicates if the operation succeeded or failed.";
|
|
1179
1219
|
}
|
|
1180
1220
|
if (!sdkResponseType) {
|
|
1181
1221
|
if (literalContentTypeHeader) {
|
|
@@ -1187,43 +1227,48 @@ export class ClientAdapter {
|
|
|
1187
1227
|
respHeaders: pageableRespHeadersMap,
|
|
1188
1228
|
};
|
|
1189
1229
|
}
|
|
1190
|
-
if (sdkResponseType.kind ===
|
|
1230
|
+
if (sdkResponseType.kind === "nullable") {
|
|
1191
1231
|
// unwrap the nullable type, this will only happen for operations with two responses and one of them does not have a body
|
|
1192
1232
|
sdkResponseType = sdkResponseType.type;
|
|
1193
1233
|
}
|
|
1194
1234
|
// for paged methods, tcgc models the method response type as an Array<T>.
|
|
1195
1235
|
// however, we want the synthesized paged response envelope as that's what Go returns.
|
|
1196
|
-
if (sdkMethod.kind ===
|
|
1236
|
+
if (sdkMethod.kind === "lropaging" || sdkMethod.kind === "paging") {
|
|
1197
1237
|
// grab the paged response envelope type from the operation responses
|
|
1198
|
-
sdkResponseType =
|
|
1238
|
+
sdkResponseType =
|
|
1239
|
+
sdkMethod.kind === "lropaging"
|
|
1240
|
+
? sdkMethod.lroMetadata.finalResponse?.result
|
|
1241
|
+
: sdkMethod.operation.responses[0].type;
|
|
1199
1242
|
if (!sdkResponseType) {
|
|
1200
|
-
throw new AdapterError(
|
|
1243
|
+
throw new AdapterError("InternalError", `paged method ${method.name} has no synthesized response type`, sdkMethod.__raw?.node);
|
|
1201
1244
|
}
|
|
1202
|
-
else if (sdkResponseType.kind !==
|
|
1203
|
-
throw new AdapterError(
|
|
1245
|
+
else if (sdkResponseType.kind !== "model") {
|
|
1246
|
+
throw new AdapterError("UnsupportedTsp", `paged method ${method.name} synthesized response type has unexpected kind ${sdkResponseType.kind}`, sdkMethod.__raw?.node);
|
|
1204
1247
|
}
|
|
1205
1248
|
}
|
|
1206
1249
|
// we have a response type, determine the content type
|
|
1207
1250
|
let contentType;
|
|
1208
|
-
if (sdkMethod.kind ===
|
|
1251
|
+
if (sdkMethod.kind === "lro" || sdkMethod.kind === "lropaging") {
|
|
1209
1252
|
// we can't grovel through the operation responses for LROs as some of them
|
|
1210
1253
|
// return only headers, thus have no content type. while it's highly likely
|
|
1211
1254
|
// to only ever be JSON, this will be broken for LROs that return text/plain
|
|
1212
1255
|
// or a binary response. the former seems unlikely, the latter though...??
|
|
1213
1256
|
// TODO: https://github.com/Azure/typespec-azure/issues/535
|
|
1214
|
-
contentType =
|
|
1257
|
+
contentType = "JSON";
|
|
1215
1258
|
}
|
|
1216
|
-
else if (sdkResponseType.kind ===
|
|
1259
|
+
else if (sdkResponseType.kind === "bytes" && sdkResponseType.encode === "bytes") {
|
|
1217
1260
|
// bytes type with bytes encoding indicates a streaming binary response
|
|
1218
|
-
contentType =
|
|
1261
|
+
contentType = "binary";
|
|
1219
1262
|
}
|
|
1220
|
-
else if (sdkResponseType.kind ===
|
|
1263
|
+
else if (sdkResponseType.kind === "union") {
|
|
1221
1264
|
// this is a multi-response operation, we assume the content-type to be JSON
|
|
1222
|
-
contentType =
|
|
1265
|
+
contentType = "JSON";
|
|
1223
1266
|
}
|
|
1224
1267
|
else {
|
|
1225
1268
|
for (const httpResp of sdkMethod.operation.responses) {
|
|
1226
|
-
if (!httpResp.type ||
|
|
1269
|
+
if (!httpResp.type ||
|
|
1270
|
+
!httpResp.defaultContentType ||
|
|
1271
|
+
httpResp.type.kind !== sdkResponseType.kind) {
|
|
1227
1272
|
continue;
|
|
1228
1273
|
}
|
|
1229
1274
|
contentType = this.adaptContentType(httpResp.defaultContentType);
|
|
@@ -1231,20 +1276,20 @@ export class ClientAdapter {
|
|
|
1231
1276
|
}
|
|
1232
1277
|
}
|
|
1233
1278
|
if (!contentType) {
|
|
1234
|
-
throw new AdapterError(
|
|
1279
|
+
throw new AdapterError("InternalError", `didn't find HTTP response for kind ${sdkResponseType.kind} in method ${method.name}`, sdkResponseType.__raw?.node);
|
|
1235
1280
|
}
|
|
1236
|
-
if (contentType ===
|
|
1281
|
+
if (contentType === "binary") {
|
|
1237
1282
|
if (literalContentTypeHeader) {
|
|
1238
1283
|
respEnv.headers.push(literalContentTypeHeader);
|
|
1239
1284
|
}
|
|
1240
|
-
respEnv.result = new go.BinaryResult(
|
|
1241
|
-
respEnv.result.docs.summary =
|
|
1285
|
+
respEnv.result = new go.BinaryResult("Body");
|
|
1286
|
+
respEnv.result.docs.summary = "Body contains the streaming response.";
|
|
1242
1287
|
return {
|
|
1243
1288
|
respEnv: respEnv,
|
|
1244
1289
|
respHeaders: pageableRespHeadersMap,
|
|
1245
1290
|
};
|
|
1246
1291
|
}
|
|
1247
|
-
else if (sdkResponseType.kind ===
|
|
1292
|
+
else if (sdkResponseType.kind === "model") {
|
|
1248
1293
|
let modelType;
|
|
1249
1294
|
const modelName = helpers.getEffectiveName(sdkResponseType).toUpperCase();
|
|
1250
1295
|
for (const model of this.ta.getPkg().models) {
|
|
@@ -1254,9 +1299,9 @@ export class ClientAdapter {
|
|
|
1254
1299
|
}
|
|
1255
1300
|
}
|
|
1256
1301
|
if (!modelType) {
|
|
1257
|
-
throw new AdapterError(
|
|
1302
|
+
throw new AdapterError("InternalError", `didn't find model type name ${sdkResponseType.name} for response envelope ${respEnv.name}`, sdkResponseType.__raw?.node);
|
|
1258
1303
|
}
|
|
1259
|
-
if (modelType.kind ===
|
|
1304
|
+
if (modelType.kind === "polymorphicModel") {
|
|
1260
1305
|
// For polymorphic models, check if we can find a concrete type that matches the discriminator value
|
|
1261
1306
|
// If no concrete type is found, create a PolymorphicResult that uses the interface type
|
|
1262
1307
|
// else use the concrete type as the result type
|
|
@@ -1266,15 +1311,15 @@ export class ClientAdapter {
|
|
|
1266
1311
|
}
|
|
1267
1312
|
}
|
|
1268
1313
|
if (respEnv.result === undefined) {
|
|
1269
|
-
if (contentType !==
|
|
1270
|
-
throw new AdapterError(
|
|
1314
|
+
if (contentType !== "JSON" && contentType !== "XML") {
|
|
1315
|
+
throw new AdapterError("InternalError", `unexpected content type ${contentType} for model ${modelType.name}`);
|
|
1271
1316
|
}
|
|
1272
1317
|
respEnv.result = new go.ModelResult(modelType, contentType);
|
|
1273
1318
|
}
|
|
1274
1319
|
respEnv.result.docs.summary = sdkResponseType.summary;
|
|
1275
1320
|
respEnv.result.docs.description = sdkResponseType.doc;
|
|
1276
1321
|
}
|
|
1277
|
-
else if (sdkResponseType.kind ===
|
|
1322
|
+
else if (sdkResponseType.kind === "union") {
|
|
1278
1323
|
// multi-response
|
|
1279
1324
|
const resultTypes = {};
|
|
1280
1325
|
const possibleTypes = new Set();
|
|
@@ -1295,27 +1340,28 @@ export class ClientAdapter {
|
|
|
1295
1340
|
resultTypes[resp.statusCodes] = respType;
|
|
1296
1341
|
}
|
|
1297
1342
|
}
|
|
1298
|
-
respEnv.result = new go.AnyResult(
|
|
1299
|
-
respEnv.result.docs.summary = `Possible types are ${[...possibleTypes].sort().join(
|
|
1343
|
+
respEnv.result = new go.AnyResult("Value", contentType, resultTypes);
|
|
1344
|
+
respEnv.result.docs.summary = `Possible types are ${[...possibleTypes].sort().join(", ")}`;
|
|
1300
1345
|
}
|
|
1301
1346
|
else {
|
|
1302
1347
|
const resultType = this.ta.getWireType(sdkResponseType, false, false);
|
|
1303
1348
|
if (go.isMonomorphicResultType(resultType)) {
|
|
1304
1349
|
let fieldName;
|
|
1305
1350
|
let xmlInfo;
|
|
1306
|
-
if (contentType ===
|
|
1351
|
+
if (contentType === "XML" && sdkResponseType.kind === "array") {
|
|
1307
1352
|
// this is for compat with autorest.go
|
|
1308
1353
|
xmlInfo = new go.XMLInfo();
|
|
1309
1354
|
fieldName = sdkResponseType.name;
|
|
1310
1355
|
const elementType = resultType.elementType;
|
|
1311
1356
|
const elementTypeXmlName = helpers.hasXMLInfo(elementType)?.name;
|
|
1312
|
-
xmlInfo.wraps =
|
|
1357
|
+
xmlInfo.wraps =
|
|
1358
|
+
elementTypeXmlName ?? go.getTypeDeclaration(elementType, method.receiver.type.pkg);
|
|
1313
1359
|
}
|
|
1314
1360
|
if (!fieldName) {
|
|
1315
1361
|
fieldName = this.recursiveTypeName(sdkResponseType, false);
|
|
1316
1362
|
}
|
|
1317
1363
|
// the monomorphicResponseFieldName decorator always wins when present
|
|
1318
|
-
const customName = helpers.getClientOption(
|
|
1364
|
+
const customName = helpers.getClientOption("monomorphicResponseFieldName", sdkMethod, this.ta.ctx.program);
|
|
1319
1365
|
if (customName) {
|
|
1320
1366
|
fieldName = customName;
|
|
1321
1367
|
}
|
|
@@ -1323,7 +1369,7 @@ export class ClientAdapter {
|
|
|
1323
1369
|
respEnv.result.xml = xmlInfo;
|
|
1324
1370
|
}
|
|
1325
1371
|
else {
|
|
1326
|
-
throw new AdapterError(
|
|
1372
|
+
throw new AdapterError("InternalError", `invalid monomorphic result type ${resultType.kind}`, sdkResponseType.__raw?.node);
|
|
1327
1373
|
}
|
|
1328
1374
|
}
|
|
1329
1375
|
return {
|
|
@@ -1345,49 +1391,49 @@ export class ClientAdapter {
|
|
|
1345
1391
|
recursiveTypeName(type, fromArray) {
|
|
1346
1392
|
if (!fromArray) {
|
|
1347
1393
|
switch (type.kind) {
|
|
1348
|
-
case
|
|
1394
|
+
case "array":
|
|
1349
1395
|
return `${this.recursiveTypeName(type.valueType, true)}Array`;
|
|
1350
|
-
case
|
|
1396
|
+
case "nullable":
|
|
1351
1397
|
return this.recursiveTypeName(type.type, false);
|
|
1352
|
-
case
|
|
1353
|
-
return this.ta.codeModel.options.rawJSONAsBytes ?
|
|
1398
|
+
case "unknown":
|
|
1399
|
+
return this.ta.codeModel.options.rawJSONAsBytes ? "RawJSON" : "Interface";
|
|
1354
1400
|
default:
|
|
1355
|
-
return
|
|
1401
|
+
return "Value";
|
|
1356
1402
|
}
|
|
1357
1403
|
}
|
|
1358
1404
|
switch (type.kind) {
|
|
1359
|
-
case
|
|
1405
|
+
case "array":
|
|
1360
1406
|
return `${this.recursiveTypeName(type.valueType, true)}Array`;
|
|
1361
|
-
case
|
|
1362
|
-
return
|
|
1363
|
-
case
|
|
1364
|
-
return
|
|
1365
|
-
case
|
|
1366
|
-
case
|
|
1407
|
+
case "boolean":
|
|
1408
|
+
return "Bool";
|
|
1409
|
+
case "bytes":
|
|
1410
|
+
return "ByteArray";
|
|
1411
|
+
case "enum":
|
|
1412
|
+
case "model":
|
|
1367
1413
|
return helpers.getEffectiveName(type);
|
|
1368
|
-
case
|
|
1369
|
-
case
|
|
1370
|
-
return
|
|
1371
|
-
case
|
|
1372
|
-
case
|
|
1373
|
-
return
|
|
1374
|
-
case
|
|
1414
|
+
case "utcDateTime":
|
|
1415
|
+
case "offsetDateTime":
|
|
1416
|
+
return "Time";
|
|
1417
|
+
case "decimal":
|
|
1418
|
+
case "decimal128":
|
|
1419
|
+
return "Float64";
|
|
1420
|
+
case "dict":
|
|
1375
1421
|
return `MapOf${this.recursiveTypeName(type.valueType, fromArray)}`;
|
|
1376
|
-
case
|
|
1377
|
-
case
|
|
1378
|
-
case
|
|
1379
|
-
case
|
|
1380
|
-
case
|
|
1381
|
-
case
|
|
1422
|
+
case "float32":
|
|
1423
|
+
case "float64":
|
|
1424
|
+
case "int16":
|
|
1425
|
+
case "int32":
|
|
1426
|
+
case "int64":
|
|
1427
|
+
case "int8":
|
|
1382
1428
|
return capitalize(type.kind);
|
|
1383
|
-
case
|
|
1429
|
+
case "nullable":
|
|
1384
1430
|
return this.recursiveTypeName(type.type, fromArray);
|
|
1385
|
-
case
|
|
1386
|
-
case
|
|
1387
|
-
case
|
|
1388
|
-
return
|
|
1389
|
-
case
|
|
1390
|
-
return this.ta.codeModel.options.rawJSONAsBytes ?
|
|
1431
|
+
case "duration":
|
|
1432
|
+
case "string":
|
|
1433
|
+
case "url":
|
|
1434
|
+
return "String";
|
|
1435
|
+
case "unknown":
|
|
1436
|
+
return this.ta.codeModel.options.rawJSONAsBytes ? "RawJSON" : "Interface";
|
|
1391
1437
|
default:
|
|
1392
1438
|
throw new Error(`unhandled monomorphic response type kind ${type.kind}`);
|
|
1393
1439
|
}
|
|
@@ -1396,10 +1442,11 @@ export class ClientAdapter {
|
|
|
1396
1442
|
const structType = new go.Struct(this.ta.getPkg(), paramGroup.groupName);
|
|
1397
1443
|
structType.docs = paramGroup.docs;
|
|
1398
1444
|
for (const param of paramGroup.params) {
|
|
1399
|
-
if (param.style ===
|
|
1445
|
+
if (param.style === "literal") {
|
|
1400
1446
|
continue;
|
|
1401
1447
|
}
|
|
1402
|
-
let byValue = param.style ===
|
|
1448
|
+
let byValue = param.style === "required" ||
|
|
1449
|
+
(param.location === "client" && go.isClientSideDefault(param.style));
|
|
1403
1450
|
// if the param isn't required, check if it should be passed by value or not.
|
|
1404
1451
|
// optional params that are implicitly nil-able shouldn't be pointer-to-type.
|
|
1405
1452
|
if (!byValue) {
|
|
@@ -1422,29 +1469,29 @@ export class ClientAdapter {
|
|
|
1422
1469
|
if (go.isHeaderScalarType(type)) {
|
|
1423
1470
|
return type;
|
|
1424
1471
|
}
|
|
1425
|
-
throw new AdapterError(
|
|
1472
|
+
throw new AdapterError("InternalError", `unexpected header scalar parameter type ${type.kind}`, sdkType.__raw?.node);
|
|
1426
1473
|
}
|
|
1427
1474
|
adaptPathScalarParameterType(sdkType) {
|
|
1428
1475
|
const type = this.ta.getWireType(sdkType, false, false);
|
|
1429
1476
|
if (go.isPathScalarParameterType(type)) {
|
|
1430
1477
|
return type;
|
|
1431
1478
|
}
|
|
1432
|
-
throw new AdapterError(
|
|
1479
|
+
throw new AdapterError("InternalError", `unexpected path scalar parameter type ${sdkType.kind}`, sdkType.__raw?.node);
|
|
1433
1480
|
}
|
|
1434
1481
|
adaptQueryScalarParameterType(sdkType) {
|
|
1435
1482
|
const type = this.ta.getWireType(sdkType, false, false);
|
|
1436
1483
|
if (go.isQueryScalarParameterType(type)) {
|
|
1437
1484
|
return type;
|
|
1438
1485
|
}
|
|
1439
|
-
throw new AdapterError(
|
|
1486
|
+
throw new AdapterError("InternalError", `unexpected query scalar parameter type ${sdkType.kind}`, sdkType.__raw?.node);
|
|
1440
1487
|
}
|
|
1441
1488
|
adaptParameterStyle(param) {
|
|
1442
1489
|
// NOTE: must check for constant type first as it will also set clientDefaultValue
|
|
1443
|
-
if (param.type.kind ===
|
|
1490
|
+
if (param.type.kind === "constant") {
|
|
1444
1491
|
if (param.optional) {
|
|
1445
|
-
return
|
|
1492
|
+
return "flag";
|
|
1446
1493
|
}
|
|
1447
|
-
return
|
|
1494
|
+
return "literal";
|
|
1448
1495
|
}
|
|
1449
1496
|
else if (param.clientDefaultValue) {
|
|
1450
1497
|
let adaptedType;
|
|
@@ -1456,21 +1503,21 @@ export class ClientAdapter {
|
|
|
1456
1503
|
else {
|
|
1457
1504
|
const adaptedWireType = this.ta.getWireType(param.type, false, false);
|
|
1458
1505
|
if (!go.isLiteralValueType(adaptedWireType)) {
|
|
1459
|
-
throw new AdapterError(
|
|
1506
|
+
throw new AdapterError("InternalError", `unexpected client side default kind ${adaptedWireType.kind} for parameter ${param.name}`, param.__raw?.node);
|
|
1460
1507
|
}
|
|
1461
1508
|
adaptedType = adaptedWireType;
|
|
1462
1509
|
}
|
|
1463
1510
|
return new go.ClientSideDefault(this.ta.getLiteral(adaptedType, param.clientDefaultValue, helpers.isExtensibleEnum(param.type)));
|
|
1464
1511
|
}
|
|
1465
1512
|
else if (param.optional) {
|
|
1466
|
-
return
|
|
1513
|
+
return "optional";
|
|
1467
1514
|
}
|
|
1468
1515
|
else {
|
|
1469
|
-
return
|
|
1516
|
+
return "required";
|
|
1470
1517
|
}
|
|
1471
1518
|
}
|
|
1472
1519
|
adaptHttpOperationExamples(sdkMethod, method, paramMapping) {
|
|
1473
|
-
if (sdkMethod.operation.examples && sdkMethod.access !==
|
|
1520
|
+
if (sdkMethod.operation.examples && sdkMethod.access !== "internal") {
|
|
1474
1521
|
for (const example of sdkMethod.operation.examples) {
|
|
1475
1522
|
try {
|
|
1476
1523
|
const goExample = new go.MethodExample(example.name, { summary: example.doc }, example.filePath);
|
|
@@ -1479,14 +1526,14 @@ export class ClientAdapter {
|
|
|
1479
1526
|
// skip the api-version param as it's not a formal parameter
|
|
1480
1527
|
continue;
|
|
1481
1528
|
}
|
|
1482
|
-
else if (param.parameter.type.kind ===
|
|
1529
|
+
else if (param.parameter.type.kind === "constant") {
|
|
1483
1530
|
// if the param's type is a constant then it's embedded
|
|
1484
1531
|
// in the code and not a formal parameter so skip it
|
|
1485
1532
|
continue;
|
|
1486
1533
|
}
|
|
1487
1534
|
const goParams = paramMapping.get(param.parameter);
|
|
1488
1535
|
if (!goParams) {
|
|
1489
|
-
throw new AdapterError(
|
|
1536
|
+
throw new AdapterError("InternalError", `can not find go param for example param ${param.parameter.name}`);
|
|
1490
1537
|
}
|
|
1491
1538
|
if (goParams.length > 1) {
|
|
1492
1539
|
// spread case
|
|
@@ -1533,7 +1580,7 @@ export class ClientAdapter {
|
|
|
1533
1580
|
if (helpers.isOmittedResponseHeader(header.header, sdkMethod, this.ta.ctx.program)) {
|
|
1534
1581
|
continue;
|
|
1535
1582
|
}
|
|
1536
|
-
throw new AdapterError(
|
|
1583
|
+
throw new AdapterError("InternalError", `can not find go header for example header ${header.header.serializedName}`);
|
|
1537
1584
|
}
|
|
1538
1585
|
goExample.responseEnvelope.headers.push(new go.ResponseHeaderExample(goHeader, this.adaptExampleType(header.value, goHeader.type)));
|
|
1539
1586
|
}
|
|
@@ -1543,20 +1590,20 @@ export class ClientAdapter {
|
|
|
1543
1590
|
// TODO: https://github.com/Azure/typespec-azure/issues/1688
|
|
1544
1591
|
if (response.bodyValue && method.returns.result) {
|
|
1545
1592
|
switch (method.returns.result.kind) {
|
|
1546
|
-
case
|
|
1593
|
+
case "anyResult":
|
|
1547
1594
|
// use the response type for 200 response
|
|
1548
1595
|
goExample.responseEnvelope.result = this.adaptExampleType(response.bodyValue, method.returns.result.httpStatusCodeType[200]);
|
|
1549
1596
|
break;
|
|
1550
|
-
case
|
|
1551
|
-
goExample.responseEnvelope.result = this.adaptExampleType(response.bodyValue, new go.Scalar(
|
|
1597
|
+
case "binaryResult":
|
|
1598
|
+
goExample.responseEnvelope.result = this.adaptExampleType(response.bodyValue, new go.Scalar("byte", false));
|
|
1552
1599
|
break;
|
|
1553
|
-
case
|
|
1600
|
+
case "modelResult":
|
|
1554
1601
|
goExample.responseEnvelope.result = this.adaptExampleType(response.bodyValue, method.returns.result.modelType);
|
|
1555
1602
|
break;
|
|
1556
|
-
case
|
|
1603
|
+
case "monomorphicResult":
|
|
1557
1604
|
goExample.responseEnvelope.result = this.adaptExampleType(response.bodyValue, method.returns.result.monomorphicType);
|
|
1558
1605
|
break;
|
|
1559
|
-
case
|
|
1606
|
+
case "polymorphicResult":
|
|
1560
1607
|
goExample.responseEnvelope.result = this.adaptExampleType(response.bodyValue, method.returns.result.interface);
|
|
1561
1608
|
break;
|
|
1562
1609
|
}
|
|
@@ -1576,45 +1623,45 @@ export class ClientAdapter {
|
|
|
1576
1623
|
}
|
|
1577
1624
|
adaptExampleType(exampleType, goType) {
|
|
1578
1625
|
switch (exampleType.kind) {
|
|
1579
|
-
case
|
|
1626
|
+
case "string":
|
|
1580
1627
|
switch (goType.kind) {
|
|
1581
|
-
case
|
|
1582
|
-
case
|
|
1583
|
-
case
|
|
1584
|
-
case
|
|
1585
|
-
case
|
|
1586
|
-
case
|
|
1587
|
-
case
|
|
1588
|
-
case
|
|
1628
|
+
case "constant":
|
|
1629
|
+
case "encodedBytes":
|
|
1630
|
+
case "etag":
|
|
1631
|
+
case "literal":
|
|
1632
|
+
case "readSeekCloser":
|
|
1633
|
+
case "scalar":
|
|
1634
|
+
case "string":
|
|
1635
|
+
case "time":
|
|
1589
1636
|
return new go.StringExample(exampleType.value, goType);
|
|
1590
1637
|
}
|
|
1591
1638
|
break;
|
|
1592
|
-
case
|
|
1639
|
+
case "number":
|
|
1593
1640
|
switch (goType.kind) {
|
|
1594
|
-
case
|
|
1595
|
-
case
|
|
1596
|
-
case
|
|
1597
|
-
case
|
|
1641
|
+
case "constant":
|
|
1642
|
+
case "literal":
|
|
1643
|
+
case "scalar":
|
|
1644
|
+
case "time":
|
|
1598
1645
|
return new go.NumberExample(exampleType.value, goType);
|
|
1599
1646
|
}
|
|
1600
1647
|
break;
|
|
1601
|
-
case
|
|
1648
|
+
case "boolean":
|
|
1602
1649
|
switch (goType.kind) {
|
|
1603
|
-
case
|
|
1604
|
-
case
|
|
1605
|
-
case
|
|
1650
|
+
case "constant":
|
|
1651
|
+
case "literal":
|
|
1652
|
+
case "scalar":
|
|
1606
1653
|
return new go.BooleanExample(exampleType.value, goType);
|
|
1607
1654
|
}
|
|
1608
1655
|
break;
|
|
1609
|
-
case
|
|
1656
|
+
case "null":
|
|
1610
1657
|
return new go.NullExample(goType);
|
|
1611
|
-
case
|
|
1612
|
-
if (goType.kind ===
|
|
1658
|
+
case "unknown":
|
|
1659
|
+
if (goType.kind === "any") {
|
|
1613
1660
|
return new go.AnyExample(exampleType.value);
|
|
1614
1661
|
}
|
|
1615
1662
|
break;
|
|
1616
|
-
case
|
|
1617
|
-
if (goType.kind ===
|
|
1663
|
+
case "array":
|
|
1664
|
+
if (goType.kind === "slice") {
|
|
1618
1665
|
const ret = new go.ArrayExample(goType);
|
|
1619
1666
|
for (const v of exampleType.value) {
|
|
1620
1667
|
ret.value.push(this.adaptExampleType(v, goType.elementType));
|
|
@@ -1622,8 +1669,8 @@ export class ClientAdapter {
|
|
|
1622
1669
|
return ret;
|
|
1623
1670
|
}
|
|
1624
1671
|
break;
|
|
1625
|
-
case
|
|
1626
|
-
if (goType.kind ===
|
|
1672
|
+
case "dict":
|
|
1673
|
+
if (goType.kind === "map") {
|
|
1627
1674
|
const ret = new go.DictionaryExample(goType);
|
|
1628
1675
|
for (const [k, v] of Object.entries(exampleType.value)) {
|
|
1629
1676
|
ret.value[k] = this.adaptExampleType(v, goType.valueType);
|
|
@@ -1631,14 +1678,17 @@ export class ClientAdapter {
|
|
|
1631
1678
|
return ret;
|
|
1632
1679
|
}
|
|
1633
1680
|
break;
|
|
1634
|
-
case
|
|
1635
|
-
throw new AdapterError(
|
|
1636
|
-
case
|
|
1637
|
-
if (goType.kind ===
|
|
1681
|
+
case "union":
|
|
1682
|
+
throw new AdapterError("UnsupportedTsp", "unsupported example type kind union");
|
|
1683
|
+
case "model":
|
|
1684
|
+
if (goType.kind === "interface" ||
|
|
1685
|
+
goType.kind === "model" ||
|
|
1686
|
+
goType.kind === "polymorphicModel") {
|
|
1638
1687
|
let concreteType;
|
|
1639
|
-
if (goType.kind ===
|
|
1688
|
+
if (goType.kind === "interface") {
|
|
1640
1689
|
concreteType = goType.possibleTypes.find((t) => t.discriminatorValue?.literal === exampleType.type.discriminatorValue ||
|
|
1641
|
-
(t.discriminatorValue?.literal).value ===
|
|
1690
|
+
(t.discriminatorValue?.literal).value ===
|
|
1691
|
+
exampleType.type.discriminatorValue);
|
|
1642
1692
|
if (concreteType === undefined) {
|
|
1643
1693
|
// can't find the sub type of a discriminated type, fallback to the base type
|
|
1644
1694
|
concreteType = goType.rootType;
|
|
@@ -1648,13 +1698,13 @@ export class ClientAdapter {
|
|
|
1648
1698
|
concreteType = goType;
|
|
1649
1699
|
}
|
|
1650
1700
|
if (concreteType === undefined) {
|
|
1651
|
-
throw new AdapterError(
|
|
1701
|
+
throw new AdapterError("InternalError", `can not find concrete type for example type ${exampleType.type.name}`);
|
|
1652
1702
|
}
|
|
1653
1703
|
const ret = new go.StructExample(concreteType);
|
|
1654
1704
|
for (const [k, v] of Object.entries(exampleType.value)) {
|
|
1655
1705
|
const field = concreteType.fields.find((f) => f.serializedName === k);
|
|
1656
1706
|
if (!field) {
|
|
1657
|
-
throw new AdapterError(
|
|
1707
|
+
throw new AdapterError("InternalError", `field with serializedName '${k}' not found in model '${concreteType.name}'.`);
|
|
1658
1708
|
}
|
|
1659
1709
|
ret.value[field.name] = this.adaptExampleType(v, field.type);
|
|
1660
1710
|
}
|
|
@@ -1663,13 +1713,13 @@ export class ClientAdapter {
|
|
|
1663
1713
|
for (const [k, v] of Object.entries(exampleType.additionalPropertiesValue)) {
|
|
1664
1714
|
const filed = concreteType.fields.find((f) => f.annotations.isAdditionalProperties);
|
|
1665
1715
|
if (!filed) {
|
|
1666
|
-
throw new AdapterError(
|
|
1716
|
+
throw new AdapterError("InternalError", `additional properties field not found in model '${concreteType.name}'.`);
|
|
1667
1717
|
}
|
|
1668
|
-
if (filed.type.kind ===
|
|
1718
|
+
if (filed.type.kind === "map") {
|
|
1669
1719
|
ret.additionalProperties[k] = this.adaptExampleType(v, filed.type.valueType);
|
|
1670
1720
|
}
|
|
1671
1721
|
else {
|
|
1672
|
-
throw new AdapterError(
|
|
1722
|
+
throw new AdapterError("InternalError", `additional properties field type should be map type, but got '${filed.type.kind}' in model '${concreteType.name}'`);
|
|
1673
1723
|
}
|
|
1674
1724
|
}
|
|
1675
1725
|
}
|
|
@@ -1677,7 +1727,7 @@ export class ClientAdapter {
|
|
|
1677
1727
|
}
|
|
1678
1728
|
break;
|
|
1679
1729
|
}
|
|
1680
|
-
throw new AdapterError(
|
|
1730
|
+
throw new AdapterError("InternalError", `can not map go type into example type ${exampleType.kind}`);
|
|
1681
1731
|
}
|
|
1682
1732
|
}
|
|
1683
1733
|
function isHttpStatusCodeRange(statusCode) {
|
|
@@ -1693,7 +1743,7 @@ function isMultipartBodyType(type) {
|
|
|
1693
1743
|
// multipart body params are always a model type.
|
|
1694
1744
|
// note that it's legal for models to have zero
|
|
1695
1745
|
// properties, so they would never be multipart.
|
|
1696
|
-
if (type.kind !==
|
|
1746
|
+
if (type.kind !== "model" || type.properties.length === 0) {
|
|
1697
1747
|
return false;
|
|
1698
1748
|
}
|
|
1699
1749
|
// check for multipart serialization options.
|