@azure-tools/typespec-go 0.8.2 → 0.8.3
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/dist/codegen.go/src/clientFactory.d.ts.map +1 -1
- package/dist/codegen.go/src/clientFactory.js +4 -0
- package/dist/codegen.go/src/clientFactory.js.map +1 -1
- package/dist/codegen.go/src/cloudConfig.d.ts +10 -0
- package/dist/codegen.go/src/cloudConfig.d.ts.map +1 -0
- package/dist/codegen.go/src/cloudConfig.js +65 -0
- package/dist/codegen.go/src/cloudConfig.js.map +1 -0
- package/dist/codegen.go/src/example.d.ts.map +1 -1
- package/dist/codegen.go/src/example.js +98 -109
- package/dist/codegen.go/src/example.js.map +1 -1
- package/dist/codegen.go/src/fake/factory.d.ts.map +1 -1
- package/dist/codegen.go/src/fake/factory.js +11 -2
- package/dist/codegen.go/src/fake/factory.js.map +1 -1
- package/dist/codegen.go/src/fake/servers.d.ts.map +1 -1
- package/dist/codegen.go/src/fake/servers.js +58 -65
- package/dist/codegen.go/src/fake/servers.js.map +1 -1
- package/dist/codegen.go/src/helpers.d.ts +36 -3
- package/dist/codegen.go/src/helpers.d.ts.map +1 -1
- package/dist/codegen.go/src/helpers.js +72 -17
- package/dist/codegen.go/src/helpers.js.map +1 -1
- package/dist/codegen.go/src/imports.d.ts +1 -1
- package/dist/codegen.go/src/imports.d.ts.map +1 -1
- package/dist/codegen.go/src/imports.js +4 -6
- package/dist/codegen.go/src/imports.js.map +1 -1
- package/dist/codegen.go/src/models.d.ts +0 -1
- package/dist/codegen.go/src/models.d.ts.map +1 -1
- package/dist/codegen.go/src/models.js +1 -7
- package/dist/codegen.go/src/models.js.map +1 -1
- package/dist/codegen.go/src/operations.d.ts.map +1 -1
- package/dist/codegen.go/src/operations.js +349 -141
- package/dist/codegen.go/src/operations.js.map +1 -1
- package/dist/codegen.go/src/responses.d.ts.map +1 -1
- package/dist/codegen.go/src/responses.js +2 -3
- package/dist/codegen.go/src/responses.js.map +1 -1
- package/dist/codemodel.go/src/client.d.ts +99 -35
- package/dist/codemodel.go/src/client.d.ts.map +1 -1
- package/dist/codemodel.go/src/client.js +53 -13
- package/dist/codemodel.go/src/client.js.map +1 -1
- package/dist/codemodel.go/src/examples.d.ts +3 -11
- package/dist/codemodel.go/src/examples.d.ts.map +1 -1
- package/dist/codemodel.go/src/examples.js +0 -7
- package/dist/codemodel.go/src/examples.js.map +1 -1
- package/dist/codemodel.go/src/index.d.ts.map +1 -1
- package/dist/codemodel.go/src/index.js +1 -0
- package/dist/codemodel.go/src/index.js.map +1 -1
- package/dist/codemodel.go/src/method.d.ts +44 -0
- package/dist/codemodel.go/src/method.d.ts.map +1 -0
- package/dist/codemodel.go/src/method.js +30 -0
- package/dist/codemodel.go/src/method.js.map +1 -0
- package/dist/codemodel.go/src/package.d.ts +2 -0
- package/dist/codemodel.go/src/package.d.ts.map +1 -1
- package/dist/codemodel.go/src/package.js +8 -0
- package/dist/codemodel.go/src/package.js.map +1 -1
- package/dist/codemodel.go/src/param.d.ts +67 -40
- package/dist/codemodel.go/src/param.d.ts.map +1 -1
- package/dist/codemodel.go/src/param.js +46 -25
- package/dist/codemodel.go/src/param.js.map +1 -1
- package/dist/codemodel.go/src/result.d.ts +1 -1
- package/dist/codemodel.go/src/result.d.ts.map +1 -1
- package/dist/codemodel.go/src/result.js +1 -1
- package/dist/codemodel.go/src/result.js.map +1 -1
- package/dist/codemodel.go/src/type.d.ts +53 -15
- package/dist/codemodel.go/src/type.d.ts.map +1 -1
- package/dist/codemodel.go/src/type.js +52 -18
- package/dist/codemodel.go/src/type.js.map +1 -1
- package/dist/typespec-go/src/emitter.d.ts +9 -0
- package/dist/typespec-go/src/emitter.d.ts.map +1 -1
- package/dist/typespec-go/src/emitter.js +37 -1
- package/dist/typespec-go/src/emitter.js.map +1 -1
- package/dist/typespec-go/src/lib.d.ts +1 -0
- package/dist/typespec-go/src/lib.d.ts.map +1 -1
- package/dist/typespec-go/src/lib.js +5 -0
- package/dist/typespec-go/src/lib.js.map +1 -1
- package/dist/typespec-go/src/tcgcadapter/adapter.d.ts.map +1 -1
- package/dist/typespec-go/src/tcgcadapter/adapter.js +4 -1
- package/dist/typespec-go/src/tcgcadapter/adapter.js.map +1 -1
- package/dist/typespec-go/src/tcgcadapter/clients.d.ts +18 -2
- package/dist/typespec-go/src/tcgcadapter/clients.d.ts.map +1 -1
- package/dist/typespec-go/src/tcgcadapter/clients.js +233 -53
- package/dist/typespec-go/src/tcgcadapter/clients.js.map +1 -1
- package/dist/typespec-go/src/tcgcadapter/types.d.ts +7 -0
- package/dist/typespec-go/src/tcgcadapter/types.d.ts.map +1 -1
- package/dist/typespec-go/src/tcgcadapter/types.js +17 -10
- package/dist/typespec-go/src/tcgcadapter/types.js.map +1 -1
- package/package.json +21 -20
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
import * as go from '../../codemodel.go/src/index.js';
|
|
6
|
+
import { ensureNameCase } from '../../naming.go/src/naming.js';
|
|
6
7
|
import { capitalize, comment, uncapitalize } from '@azure-tools/codegen';
|
|
7
8
|
import { values } from '@azure-tools/linq';
|
|
8
9
|
import * as helpers from './helpers.js';
|
|
@@ -35,20 +36,14 @@ export async function generateOperations(codeModel) {
|
|
|
35
36
|
imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/policy');
|
|
36
37
|
imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
|
|
37
38
|
}
|
|
38
|
-
|
|
39
|
-
if (azureARM) {
|
|
40
|
-
clientPkg = 'arm';
|
|
41
|
-
imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/arm');
|
|
42
|
-
client.constructors.push(createARMClientConstructor(client, imports));
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
39
|
+
if (!azureARM) {
|
|
45
40
|
imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore');
|
|
46
41
|
}
|
|
47
42
|
// generate client type
|
|
48
43
|
let clientText = helpers.formatDocComment(client.docs);
|
|
49
44
|
clientText += '// Don\'t use this type directly, use ';
|
|
50
|
-
if (client.constructors.length === 1) {
|
|
51
|
-
clientText += `${client.constructors[0].name}() instead.\n`;
|
|
45
|
+
if (client.instance?.kind === 'constructable' && client.instance.constructors.length === 1) {
|
|
46
|
+
clientText += `${client.instance.constructors[0].name}() instead.\n`;
|
|
52
47
|
}
|
|
53
48
|
else if (client.parent) {
|
|
54
49
|
// find the accessor method
|
|
@@ -68,7 +63,7 @@ export async function generateOperations(codeModel) {
|
|
|
68
63
|
clientText += 'a constructor function instead.\n';
|
|
69
64
|
}
|
|
70
65
|
clientText += `type ${client.name} struct {\n`;
|
|
71
|
-
clientText += `\tinternal *${
|
|
66
|
+
clientText += `\tinternal *${azureARM ? 'arm' : 'azcore'}.Client\n`;
|
|
72
67
|
// check for any optional host params
|
|
73
68
|
const optionalParams = new Array();
|
|
74
69
|
const isParamPointer = function (param) {
|
|
@@ -79,7 +74,7 @@ export async function generateOperations(codeModel) {
|
|
|
79
74
|
if (client.parameters.length > 0) {
|
|
80
75
|
const addedGroups = new Set();
|
|
81
76
|
for (const clientParam of values(client.parameters)) {
|
|
82
|
-
if (go.isLiteralParameter(clientParam)) {
|
|
77
|
+
if (go.isLiteralParameter(clientParam.style)) {
|
|
83
78
|
continue;
|
|
84
79
|
}
|
|
85
80
|
if (clientParam.group) {
|
|
@@ -96,7 +91,7 @@ export async function generateOperations(codeModel) {
|
|
|
96
91
|
else {
|
|
97
92
|
clientText += `${helpers.formatParameterTypeName(clientParam)}\n`;
|
|
98
93
|
}
|
|
99
|
-
if (!go.isRequiredParameter(clientParam)) {
|
|
94
|
+
if (!go.isRequiredParameter(clientParam.style)) {
|
|
100
95
|
optionalParams.push(clientParam);
|
|
101
96
|
}
|
|
102
97
|
}
|
|
@@ -106,8 +101,7 @@ export async function generateOperations(codeModel) {
|
|
|
106
101
|
if (azureARM && optionalParams.length > 0) {
|
|
107
102
|
throw new CodegenError('UnsupportedTsp', 'optional client parameters for ARM is not supported');
|
|
108
103
|
}
|
|
109
|
-
|
|
110
|
-
clientText += generateConstructors(azureARM, client, imports);
|
|
104
|
+
clientText += generateConstructors(client, imports);
|
|
111
105
|
// generate client accessors and operations
|
|
112
106
|
let opText = '';
|
|
113
107
|
for (const clientAccessor of client.clientAccessors) {
|
|
@@ -117,6 +111,9 @@ export async function generateOperations(codeModel) {
|
|
|
117
111
|
opText += '\t\tinternal: client.internal,\n';
|
|
118
112
|
// propagate all client params
|
|
119
113
|
for (const param of client.parameters) {
|
|
114
|
+
if (go.isLiteralParameter(param.style)) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
120
117
|
opText += `\t\t${param.name}: client.${param.name},\n`;
|
|
121
118
|
}
|
|
122
119
|
opText += '\t}\n}\n\n';
|
|
@@ -127,13 +124,13 @@ export async function generateOperations(codeModel) {
|
|
|
127
124
|
// it must be done before the imports are written out
|
|
128
125
|
if (go.isLROMethod(method)) {
|
|
129
126
|
// generate Begin method
|
|
130
|
-
opText += generateLROBeginMethod(
|
|
127
|
+
opText += generateLROBeginMethod(method, imports, codeModel.options.injectSpans, codeModel.options.generateFakes);
|
|
131
128
|
}
|
|
132
|
-
opText += generateOperation(
|
|
133
|
-
opText += createProtocolRequest(azureARM,
|
|
129
|
+
opText += generateOperation(method, imports, codeModel.options.injectSpans, codeModel.options.generateFakes);
|
|
130
|
+
opText += createProtocolRequest(azureARM, method, imports);
|
|
134
131
|
if (method.kind !== 'lroMethod') {
|
|
135
132
|
// LRO responses are handled elsewhere, with the exception of pageable LROs
|
|
136
|
-
opText += createProtocolResponse(
|
|
133
|
+
opText += createProtocolResponse(method, imports);
|
|
137
134
|
}
|
|
138
135
|
if ((method.kind === 'lroPageableMethod' || method.kind === 'pageableMethod') && method.nextPageMethod && !nextPageMethods.includes(method.nextPageMethod)) {
|
|
139
136
|
// track the next page methods to generate as multiple operations can use the same next page operation
|
|
@@ -141,7 +138,7 @@ export async function generateOperations(codeModel) {
|
|
|
141
138
|
}
|
|
142
139
|
}
|
|
143
140
|
for (const method of nextPageMethods) {
|
|
144
|
-
opText += createProtocolRequest(azureARM,
|
|
141
|
+
opText += createProtocolRequest(azureARM, method, imports);
|
|
145
142
|
}
|
|
146
143
|
// stitch it all together
|
|
147
144
|
let text = helpers.contentPreamble(codeModel);
|
|
@@ -152,65 +149,222 @@ export async function generateOperations(codeModel) {
|
|
|
152
149
|
}
|
|
153
150
|
return operations;
|
|
154
151
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
152
|
+
/**
|
|
153
|
+
* generates all modeled client constructors and client options types.
|
|
154
|
+
* if there are no client constructors, the empty string is returned.
|
|
155
|
+
*
|
|
156
|
+
* @param client the client for which to generate constructors and the client options type
|
|
157
|
+
* @param imports the import manager currently in scope
|
|
158
|
+
* @returns the client constructor code or the empty string
|
|
159
|
+
*/
|
|
160
|
+
function generateConstructors(client, imports) {
|
|
161
|
+
if (client.instance?.kind !== 'constructable') {
|
|
158
162
|
return '';
|
|
159
163
|
}
|
|
164
|
+
const clientOptions = client.instance.options;
|
|
160
165
|
let ctorText = '';
|
|
161
|
-
|
|
166
|
+
if (clientOptions.kind === 'clientOptions') {
|
|
167
|
+
// for non-ARM, the options type will always be a parameter group
|
|
168
|
+
ctorText += `// ${clientOptions.name} contains the optional values for creating a [${client.name}].\n`;
|
|
169
|
+
ctorText += `type ${clientOptions.name} struct {\n\tazcore.ClientOptions\n`;
|
|
170
|
+
for (const param of clientOptions.params) {
|
|
171
|
+
if (go.isAPIVersionParameter(param)) {
|
|
172
|
+
// we use azcore.ClientOptions.APIVersion
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
ctorText += helpers.formatDocCommentWithPrefix(ensureNameCase(param.name), param.docs);
|
|
176
|
+
if (go.isClientSideDefault(param.style)) {
|
|
177
|
+
if (!param.docs.description && !param.docs.summary) {
|
|
178
|
+
ctorText += '\n';
|
|
179
|
+
}
|
|
180
|
+
ctorText += `\t${comment(`The default value is ${helpers.formatLiteralValue(param.style.defaultValue, false)}`, '// ')}.\n`;
|
|
181
|
+
}
|
|
182
|
+
ctorText += `\t${ensureNameCase(param.name)} *${go.getTypeDeclaration(param.type)}\n`;
|
|
183
|
+
}
|
|
184
|
+
ctorText += '}\n\n';
|
|
185
|
+
}
|
|
186
|
+
for (const constructor of client.instance.constructors) {
|
|
162
187
|
const ctorParams = new Array();
|
|
163
188
|
const paramDocs = new Array();
|
|
164
|
-
|
|
165
|
-
|
|
189
|
+
// ctor params can also be present in the supplemental endpoint parameters
|
|
190
|
+
const consolidatedCtorParams = new Array(...constructor.parameters);
|
|
191
|
+
if (client.instance.endpoint) {
|
|
192
|
+
consolidatedCtorParams.push(...client.instance.endpoint.parameters);
|
|
193
|
+
}
|
|
194
|
+
consolidatedCtorParams.sort(helpers.sortParametersByRequired);
|
|
195
|
+
for (const ctorParam of consolidatedCtorParams) {
|
|
196
|
+
if (!go.isRequiredParameter(ctorParam.style)) {
|
|
197
|
+
// param is part of the options group
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
166
200
|
imports.addImportForType(ctorParam.type);
|
|
167
201
|
ctorParams.push(`${ctorParam.name} ${helpers.formatParameterTypeName(ctorParam)}`);
|
|
168
202
|
if (ctorParam.docs.summary || ctorParam.docs.description) {
|
|
169
203
|
paramDocs.push(helpers.formatCommentAsBulletItem(ctorParam.name, ctorParam.docs));
|
|
170
204
|
}
|
|
171
205
|
}
|
|
206
|
+
const emitProlog = function (optionsTypeName, tokenAuth, plOpts) {
|
|
207
|
+
imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
|
|
208
|
+
let bodyText = `\tif options == nil {\n\t\toptions = &${optionsTypeName}{}\n\t}\n`;
|
|
209
|
+
let apiVersionConfig = '';
|
|
210
|
+
// check if there's an api version parameter
|
|
211
|
+
let apiVersionParam;
|
|
212
|
+
for (const param of consolidatedCtorParams) {
|
|
213
|
+
switch (param.kind) {
|
|
214
|
+
case 'headerScalarParam':
|
|
215
|
+
case 'pathScalarParam':
|
|
216
|
+
case 'queryScalarParam':
|
|
217
|
+
case 'uriParam':
|
|
218
|
+
if (param.isApiVersion) {
|
|
219
|
+
apiVersionParam = param;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (tokenAuth) {
|
|
224
|
+
imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud');
|
|
225
|
+
imports.add('fmt');
|
|
226
|
+
imports.add('reflect');
|
|
227
|
+
bodyText += '\tif reflect.ValueOf(options.Cloud).IsZero() {\n';
|
|
228
|
+
bodyText += '\t\toptions.Cloud = cloud.AzurePublic\n\t}\n';
|
|
229
|
+
bodyText += '\tc, ok := options.Cloud.Services[ServiceName]\n';
|
|
230
|
+
bodyText += '\tif !ok {\n';
|
|
231
|
+
bodyText += '\t\treturn nil, fmt.Errorf("provided Cloud field is missing configuration for %s", ServiceName)\n';
|
|
232
|
+
bodyText += '\t} else if c.Audience == "" {\n';
|
|
233
|
+
bodyText += '\t\treturn nil, fmt.Errorf("provided Cloud field is missing Audience for %s", ServiceName)\n\t}\n';
|
|
234
|
+
}
|
|
235
|
+
if (apiVersionParam) {
|
|
236
|
+
let location;
|
|
237
|
+
let name;
|
|
238
|
+
switch (apiVersionParam.kind) {
|
|
239
|
+
case 'headerScalarParam':
|
|
240
|
+
location = 'Header';
|
|
241
|
+
name = apiVersionParam.headerName;
|
|
242
|
+
break;
|
|
243
|
+
case 'pathScalarParam':
|
|
244
|
+
case 'uriParam':
|
|
245
|
+
location = 'Path';
|
|
246
|
+
// name isn't used for the path case
|
|
247
|
+
break;
|
|
248
|
+
case 'queryScalarParam':
|
|
249
|
+
location = 'QueryParam';
|
|
250
|
+
name = apiVersionParam.queryParameter;
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
if (name) {
|
|
254
|
+
name = `\n\t\t\tName: "${name}",`;
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
name = '';
|
|
258
|
+
}
|
|
259
|
+
apiVersionConfig = `\n\t\tAPIVersion: runtime.APIVersionOptions{${name}\n\t\t\tLocation: runtime.APIVersionLocation${location},\n\t\t},`;
|
|
260
|
+
if (!plOpts) {
|
|
261
|
+
apiVersionConfig += '\n';
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
bodyText += `\tcl, err := azcore.NewClient(moduleName, moduleVersion, runtime.PipelineOptions{${apiVersionConfig}${plOpts ?? ''}}, &options.ClientOptions)\n`;
|
|
265
|
+
return bodyText;
|
|
266
|
+
};
|
|
267
|
+
let prolog;
|
|
268
|
+
switch (constructor.authentication.kind) {
|
|
269
|
+
case 'none':
|
|
270
|
+
if (clientOptions.kind !== 'clientOptions') {
|
|
271
|
+
throw new CodegenError('InternalError', `unexpected client options kind ${clientOptions.kind}`);
|
|
272
|
+
}
|
|
273
|
+
prolog = emitProlog(clientOptions.name, false);
|
|
274
|
+
break;
|
|
275
|
+
case 'token':
|
|
276
|
+
imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore');
|
|
277
|
+
ctorParams.push('credential azcore.TokenCredential');
|
|
278
|
+
paramDocs.push(helpers.formatCommentAsBulletItem('credential', { summary: 'used to authorize requests. Usually a credential from azidentity.' }));
|
|
279
|
+
switch (clientOptions.kind) {
|
|
280
|
+
case 'clientOptions': {
|
|
281
|
+
imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/policy');
|
|
282
|
+
const tokenPolicyOpts = '&policy.BearerTokenOptions{\n\t\t\tInsecureAllowCredentialWithHTTP: options.InsecureAllowCredentialWithHTTP,\n\t\t}';
|
|
283
|
+
// we assume a single scope. this is enforced when adapting the data from tcgc
|
|
284
|
+
const tokenPolicy = `\n\t\tPerCall: []policy.Policy{\n\t\truntime.NewBearerTokenPolicy(credential, []string{c.Audience + "${helpers.splitScope(constructor.authentication.scopes[0]).scope}"}, ${tokenPolicyOpts}),\n\t\t},\n`;
|
|
285
|
+
prolog = emitProlog(clientOptions.name, true, tokenPolicy);
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
case 'parameter':
|
|
289
|
+
// this is the ARM case
|
|
290
|
+
imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/arm');
|
|
291
|
+
prolog = '\tcl, err := arm.NewClient(moduleName, moduleVersion, credential, options)\n';
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
172
296
|
// add client options last
|
|
173
|
-
ctorParams.push(
|
|
174
|
-
paramDocs.push(helpers.formatCommentAsBulletItem(
|
|
297
|
+
ctorParams.push(`options ${helpers.formatParameterTypeName(clientOptions)}`);
|
|
298
|
+
paramDocs.push(helpers.formatCommentAsBulletItem('options', { summary: 'Contains optional client configuration. Pass nil to accept the default values.' }));
|
|
175
299
|
ctorText += `// ${constructor.name} creates a new instance of ${client.name} with the specified values.\n`;
|
|
176
300
|
for (const doc of paramDocs) {
|
|
177
301
|
ctorText += doc;
|
|
178
302
|
}
|
|
179
303
|
ctorText += `func ${constructor.name}(${ctorParams.join(', ')}) (*${client.name}, error) {\n`;
|
|
180
|
-
|
|
181
|
-
if (azureARM) {
|
|
182
|
-
clientType = 'arm';
|
|
183
|
-
}
|
|
184
|
-
ctorText += `\tcl, err := ${clientType}.NewClient(moduleName, moduleVersion, credential, options)\n`;
|
|
304
|
+
ctorText += prolog;
|
|
185
305
|
ctorText += '\tif err != nil {\n';
|
|
186
306
|
ctorText += '\t\treturn nil, err\n';
|
|
187
307
|
ctorText += '\t}\n';
|
|
308
|
+
const emitClientSideDefault = function (param) {
|
|
309
|
+
if (go.isClientSideDefault(param.style)) {
|
|
310
|
+
let name;
|
|
311
|
+
if (go.isAPIVersionParameter(param)) {
|
|
312
|
+
name = 'APIVersion';
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
name = ensureNameCase(param.name);
|
|
316
|
+
}
|
|
317
|
+
ctorText += `\t${param.name} := ${helpers.formatLiteralValue(param.style.defaultValue, false)}\n`;
|
|
318
|
+
ctorText += `\tif options.${name} != ${helpers.zeroValue(param)} {\n\t\t${param.name} = ${helpers.star(param.byValue)}options.${name}\n\t}\n`;
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
// handle any client-side defaults
|
|
322
|
+
if (clientOptions.kind === 'clientOptions') {
|
|
323
|
+
for (const param of clientOptions.params) {
|
|
324
|
+
emitClientSideDefault(param);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
// construct the supplemental path and join it to the endpoint
|
|
328
|
+
if (client.instance.endpoint) {
|
|
329
|
+
for (const param of client.instance.endpoint.parameters) {
|
|
330
|
+
emitClientSideDefault(param);
|
|
331
|
+
}
|
|
332
|
+
imports.add('strings');
|
|
333
|
+
ctorText += `\thost := "${client.instance.endpoint.path}"\n`;
|
|
334
|
+
for (const param of client.instance.endpoint.parameters) {
|
|
335
|
+
ctorText += `\thost = strings.ReplaceAll(host, "{${param.uriPathSegment}}", ${helpers.formatValue(param.name, param.type, imports)})\n`;
|
|
336
|
+
}
|
|
337
|
+
// the endpoint param is always the first ctor param
|
|
338
|
+
const endpointParam = client.instance.constructors[0].parameters[0];
|
|
339
|
+
ctorText += `\t${endpointParam.name} = runtime.JoinPaths(${endpointParam.name}, host)\n`;
|
|
340
|
+
}
|
|
188
341
|
// construct client literal
|
|
189
|
-
|
|
342
|
+
let clientVar = 'client';
|
|
343
|
+
// ensure clientVar doesn't collide with any params
|
|
344
|
+
for (const param of consolidatedCtorParams) {
|
|
345
|
+
if (param.name === clientVar) {
|
|
346
|
+
clientVar = ensureNameCase(client.name, true);
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
ctorText += `\t${clientVar} := &${client.name}{\n`;
|
|
351
|
+
// NOTE: we don't enumerate consolidatedCtorParams here
|
|
352
|
+
// as any supplemental endpoint params are ephemeral and
|
|
353
|
+
// consumed during client construction.
|
|
190
354
|
for (const parameter of values(client.parameters)) {
|
|
355
|
+
if (go.isLiteralParameter(parameter.style)) {
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
191
358
|
// each client field will have a matching parameter with the same name
|
|
192
359
|
ctorText += `\t\t${parameter.name}: ${parameter.name},\n`;
|
|
193
360
|
}
|
|
194
361
|
ctorText += '\tinternal: cl,\n';
|
|
195
362
|
ctorText += '\t}\n';
|
|
196
|
-
ctorText +=
|
|
363
|
+
ctorText += `\treturn ${clientVar}, nil\n`;
|
|
197
364
|
ctorText += '}\n\n';
|
|
198
365
|
}
|
|
199
366
|
return ctorText;
|
|
200
367
|
}
|
|
201
|
-
// creates a modeled constructor for an ARM client
|
|
202
|
-
function createARMClientConstructor(client, imports) {
|
|
203
|
-
imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/arm');
|
|
204
|
-
const ctor = new go.Constructor(`New${client.name}`);
|
|
205
|
-
// add any modeled parameter first, which should only be the subscriptionID, then add TokenCredential
|
|
206
|
-
for (const param of client.parameters) {
|
|
207
|
-
ctor.parameters.push(param);
|
|
208
|
-
}
|
|
209
|
-
const tokenCredParam = new go.Parameter('credential', new go.QualifiedType('TokenCredential', 'github.com/Azure/azure-sdk-for-go/sdk/azcore'), 'required', true, 'client');
|
|
210
|
-
tokenCredParam.docs.summary = 'used to authorize requests. Usually a credential from azidentity.';
|
|
211
|
-
ctor.parameters.push(tokenCredParam);
|
|
212
|
-
return ctor;
|
|
213
|
-
}
|
|
214
368
|
// use this to generate the code that will help process values returned in response headers
|
|
215
369
|
function formatHeaderResponseValue(headerResp, imports, respObj, zeroResp) {
|
|
216
370
|
// dictionaries are handled slightly different so we do that first
|
|
@@ -305,7 +459,7 @@ function formatHeaderResponseValue(headerResp, imports, respObj, zeroResp) {
|
|
|
305
459
|
return text;
|
|
306
460
|
}
|
|
307
461
|
function getZeroReturnValue(method, apiType) {
|
|
308
|
-
let returnType = `${method.
|
|
462
|
+
let returnType = `${method.returns.name}{}`;
|
|
309
463
|
if (go.isLROMethod(method)) {
|
|
310
464
|
if (apiType === 'api' || apiType === 'op') {
|
|
311
465
|
// the api returns a *Poller[T]
|
|
@@ -325,10 +479,10 @@ function generateNilChecks(path, prefix = 'page') {
|
|
|
325
479
|
}
|
|
326
480
|
return checks.join(' && ');
|
|
327
481
|
}
|
|
328
|
-
function emitPagerDefinition(
|
|
482
|
+
function emitPagerDefinition(method, imports, injectSpans, generateFakes) {
|
|
329
483
|
imports.add('context');
|
|
330
|
-
let text = `runtime.NewPager(runtime.PagingHandler[${method.
|
|
331
|
-
text += `\t\tMore: func(page ${method.
|
|
484
|
+
let text = `runtime.NewPager(runtime.PagingHandler[${method.returns.name}]{\n`;
|
|
485
|
+
text += `\t\tMore: func(page ${method.returns.name}) bool {\n`;
|
|
332
486
|
// there is no advancer for single-page pagers
|
|
333
487
|
if (method.nextLinkName) {
|
|
334
488
|
const nilChecks = generateNilChecks(method.nextLinkName);
|
|
@@ -339,10 +493,10 @@ function emitPagerDefinition(client, method, imports, injectSpans, generateFakes
|
|
|
339
493
|
text += '\t\t\treturn false\n';
|
|
340
494
|
text += '\t\t},\n';
|
|
341
495
|
}
|
|
342
|
-
text += `\t\tFetcher: func(ctx context.Context, page *${method.
|
|
496
|
+
text += `\t\tFetcher: func(ctx context.Context, page *${method.returns.name}) (${method.returns.name}, error) {\n`;
|
|
343
497
|
const reqParams = helpers.getCreateRequestParameters(method);
|
|
344
498
|
if (generateFakes) {
|
|
345
|
-
text += `\t\tctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "${
|
|
499
|
+
text += `\t\tctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "${method.receiver.type.name}.${fixUpMethodName(method)}")\n`;
|
|
346
500
|
}
|
|
347
501
|
if (method.nextLinkName) {
|
|
348
502
|
let nextLinkVar;
|
|
@@ -378,7 +532,7 @@ function emitPagerDefinition(client, method, imports, injectSpans, generateFakes
|
|
|
378
532
|
else {
|
|
379
533
|
text += 'nil)\n';
|
|
380
534
|
}
|
|
381
|
-
text += `\t\t\tif err != nil {\n\t\t\t\treturn ${method.
|
|
535
|
+
text += `\t\t\tif err != nil {\n\t\t\t\treturn ${method.returns.name}{}, err\n\t\t\t}\n`;
|
|
382
536
|
text += `\t\t\treturn client.${method.naming.responseMethod}(resp)\n`;
|
|
383
537
|
text += '\t\t\t},\n';
|
|
384
538
|
}
|
|
@@ -386,14 +540,14 @@ function emitPagerDefinition(client, method, imports, injectSpans, generateFakes
|
|
|
386
540
|
// this is the singular page case, no fetcher helper required
|
|
387
541
|
text += `\t\t\treq, err := client.${method.naming.requestMethod}(${reqParams})\n`;
|
|
388
542
|
text += '\t\t\tif err != nil {\n';
|
|
389
|
-
text += `\t\t\t\treturn ${method.
|
|
543
|
+
text += `\t\t\t\treturn ${method.returns.name}{}, err\n`;
|
|
390
544
|
text += '\t\t\t}\n';
|
|
391
545
|
text += '\t\t\tresp, err := client.internal.Pipeline().Do(req)\n';
|
|
392
546
|
text += '\t\t\tif err != nil {\n';
|
|
393
|
-
text += `\t\t\t\treturn ${method.
|
|
547
|
+
text += `\t\t\t\treturn ${method.returns.name}{}, err\n`;
|
|
394
548
|
text += '\t\t\t}\n';
|
|
395
549
|
text += '\t\t\tif !runtime.HasStatusCode(resp, http.StatusOK) {\n';
|
|
396
|
-
text += `\t\t\t\treturn ${method.
|
|
550
|
+
text += `\t\t\t\treturn ${method.returns.name}{}, runtime.NewResponseError(resp)\n`;
|
|
397
551
|
text += '\t\t\t}\n';
|
|
398
552
|
text += `\t\t\treturn client.${method.naming.responseMethod}(resp)\n`;
|
|
399
553
|
text += '\t\t},\n';
|
|
@@ -411,14 +565,23 @@ function genApiVersionDoc(apiVersions) {
|
|
|
411
565
|
return `//\n// Generated from API version ${apiVersions.join(', ')}\n`;
|
|
412
566
|
}
|
|
413
567
|
function genRespErrorDoc(method) {
|
|
414
|
-
if (!(method.
|
|
568
|
+
if (!(method.returns.result?.kind === 'headAsBooleanResult') && !go.isPageableMethod(method)) {
|
|
415
569
|
// when head-as-boolean is enabled, no error is returned for 4xx status codes.
|
|
416
570
|
// pager constructors don't return an error
|
|
417
571
|
return '// If the operation fails it returns an *azcore.ResponseError type.\n';
|
|
418
572
|
}
|
|
419
573
|
return '';
|
|
420
574
|
}
|
|
421
|
-
|
|
575
|
+
/**
|
|
576
|
+
* returns the receiver definition for a client
|
|
577
|
+
*
|
|
578
|
+
* @param receiver the receiver for which to emit the definition
|
|
579
|
+
* @returns the receiver definition
|
|
580
|
+
*/
|
|
581
|
+
function getClientReceiverDefinition(receiver) {
|
|
582
|
+
return `(${receiver.name} ${receiver.byValue ? '' : '*'}${receiver.type.name})`;
|
|
583
|
+
}
|
|
584
|
+
function generateOperation(method, imports, injectSpans, generateFakes) {
|
|
422
585
|
const params = getAPIParametersSig(method, imports);
|
|
423
586
|
const returns = generateReturnsInfo(method, 'op');
|
|
424
587
|
let methodName = method.name;
|
|
@@ -447,16 +610,16 @@ function generateOperation(client, method, imports, injectSpans, generateFakes)
|
|
|
447
610
|
text += helpers.formatCommentAsBulletItem(param.name, param.docs);
|
|
448
611
|
}
|
|
449
612
|
}
|
|
450
|
-
text += `func (
|
|
613
|
+
text += `func ${getClientReceiverDefinition(method.receiver)} ${methodName}(${params}) (${returns.join(', ')}) {\n`;
|
|
451
614
|
const reqParams = helpers.getCreateRequestParameters(method);
|
|
452
615
|
if (method.kind === 'pageableMethod') {
|
|
453
616
|
text += '\treturn ';
|
|
454
|
-
text += emitPagerDefinition(
|
|
617
|
+
text += emitPagerDefinition(method, imports, injectSpans, generateFakes);
|
|
455
618
|
text += '}\n\n';
|
|
456
619
|
return text;
|
|
457
620
|
}
|
|
458
621
|
text += '\tvar err error\n';
|
|
459
|
-
let operationName = `"${
|
|
622
|
+
let operationName = `"${method.receiver.type.name}.${fixUpMethodName(method)}"`;
|
|
460
623
|
if (generateFakes && injectSpans) {
|
|
461
624
|
text += `\tconst operationName = ${operationName}\n`;
|
|
462
625
|
operationName = 'operationName';
|
|
@@ -482,8 +645,8 @@ function generateOperation(client, method, imports, injectSpans, generateFakes)
|
|
|
482
645
|
text += `\t\treturn ${zeroResp}, err\n`;
|
|
483
646
|
text += '\t}\n';
|
|
484
647
|
// HAB with headers response is handled in protocol responder
|
|
485
|
-
if (method.
|
|
486
|
-
text += `\treturn ${method.
|
|
648
|
+
if (method.returns.result?.kind === 'headAsBooleanResult' && method.returns.headers.length === 0) {
|
|
649
|
+
text += `\treturn ${method.returns.name}{${method.returns.result.fieldName}: httpResp.StatusCode >= 200 && httpResp.StatusCode < 300}, nil\n`;
|
|
487
650
|
}
|
|
488
651
|
else {
|
|
489
652
|
if (go.isLROMethod(method)) {
|
|
@@ -494,32 +657,32 @@ function generateOperation(client, method, imports, injectSpans, generateFakes)
|
|
|
494
657
|
text += `\tresp, err := client.${method.naming.responseMethod}(httpResp)\n`;
|
|
495
658
|
text += '\treturn resp, err\n';
|
|
496
659
|
}
|
|
497
|
-
else if (method.
|
|
498
|
-
text += `\treturn ${method.
|
|
660
|
+
else if (method.returns.result?.kind === 'binaryResult') {
|
|
661
|
+
text += `\treturn ${method.returns.name}{${method.returns.result.fieldName}: httpResp.Body}, nil\n`;
|
|
499
662
|
}
|
|
500
663
|
else {
|
|
501
|
-
text += `\treturn ${method.
|
|
664
|
+
text += `\treturn ${method.returns.name}{}, nil\n`;
|
|
502
665
|
}
|
|
503
666
|
}
|
|
504
667
|
text += '}\n\n';
|
|
505
668
|
return text;
|
|
506
669
|
}
|
|
507
|
-
function createProtocolRequest(azureARM,
|
|
670
|
+
function createProtocolRequest(azureARM, method, imports) {
|
|
508
671
|
let name = method.name;
|
|
509
672
|
if (method.kind !== 'nextPageMethod') {
|
|
510
673
|
name = method.naming.requestMethod;
|
|
511
674
|
}
|
|
512
675
|
for (const param of values(method.parameters)) {
|
|
513
|
-
if (param.location !== 'method' || !go.isRequiredParameter(param)) {
|
|
676
|
+
if (param.location !== 'method' || !go.isRequiredParameter(param.style)) {
|
|
514
677
|
continue;
|
|
515
678
|
}
|
|
516
679
|
imports.addImportForType(param.type);
|
|
517
680
|
}
|
|
518
681
|
const returns = ['*policy.Request', 'error'];
|
|
519
682
|
let text = `${comment(name, '// ')} creates the ${method.name} request.\n`;
|
|
520
|
-
text += `func (
|
|
683
|
+
text += `func ${getClientReceiverDefinition(method.receiver)} ${name}(${helpers.getCreateRequestParametersSig(method)}) (${returns.join(', ')}) {\n`;
|
|
521
684
|
const hostParams = new Array();
|
|
522
|
-
for (const parameter of
|
|
685
|
+
for (const parameter of method.receiver.type.parameters) {
|
|
523
686
|
if (parameter.kind === 'uriParam') {
|
|
524
687
|
hostParams.push(parameter);
|
|
525
688
|
}
|
|
@@ -528,10 +691,10 @@ function createProtocolRequest(azureARM, client, method, imports) {
|
|
|
528
691
|
if (azureARM) {
|
|
529
692
|
hostParam = 'client.internal.Endpoint()';
|
|
530
693
|
}
|
|
531
|
-
else if (
|
|
694
|
+
else if (method.receiver.type.instance?.kind === 'templatedHost') {
|
|
532
695
|
imports.add('strings');
|
|
533
696
|
// we have a templated host
|
|
534
|
-
text += `\thost := "${
|
|
697
|
+
text += `\thost := "${method.receiver.type.instance.path}"\n`;
|
|
535
698
|
// get all the host params on the client
|
|
536
699
|
for (const hostParam of hostParams) {
|
|
537
700
|
text += `\thost = strings.ReplaceAll(host, "{${hostParam.uriPathSegment}}", ${helpers.formatValue(`client.${hostParam.name}`, hostParam.type, imports)})\n`;
|
|
@@ -549,7 +712,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
|
|
|
549
712
|
hostParam = 'client.' + hostParams[0].name;
|
|
550
713
|
}
|
|
551
714
|
else {
|
|
552
|
-
throw new CodegenError('InternalError', `no host or endpoint defined for method ${
|
|
715
|
+
throw new CodegenError('InternalError', `no host or endpoint defined for method ${method.receiver.type.name}.${method.name}`);
|
|
553
716
|
}
|
|
554
717
|
const methodParamGroups = helpers.getMethodParamGroups(method);
|
|
555
718
|
const hasPathParams = methodParamGroups.pathParams.length > 0;
|
|
@@ -565,36 +728,6 @@ function createProtocolRequest(azureARM, client, method, imports) {
|
|
|
565
728
|
text += `\turlPath := "${method.httpPath}"\n`;
|
|
566
729
|
hostParam = `runtime.JoinPaths(${hostParam}, urlPath)`;
|
|
567
730
|
}
|
|
568
|
-
if (hasPathParams) {
|
|
569
|
-
// swagger defines path params, emit path and replace tokens
|
|
570
|
-
imports.add('strings');
|
|
571
|
-
// replace path parameters
|
|
572
|
-
for (const pp of methodParamGroups.pathParams) {
|
|
573
|
-
// emit check to ensure path param isn't an empty string. we only need
|
|
574
|
-
// to do this for params that have an underlying type of string.
|
|
575
|
-
const choiceIsString = function (type) {
|
|
576
|
-
return type.kind === 'constant' && type.type === 'string';
|
|
577
|
-
};
|
|
578
|
-
// TODO: https://github.com/Azure/autorest.go/issues/1593
|
|
579
|
-
if (pp.kind === 'pathScalarParam' && ((pp.type.kind === 'string' || choiceIsString(pp.type)) && pp.isEncoded)) {
|
|
580
|
-
const paramName = helpers.getParamName(pp);
|
|
581
|
-
imports.add('errors');
|
|
582
|
-
text += `\tif ${paramName} == "" {\n`;
|
|
583
|
-
text += `\t\treturn nil, errors.New("parameter ${paramName} cannot be empty")\n`;
|
|
584
|
-
text += '\t}\n';
|
|
585
|
-
}
|
|
586
|
-
let paramValue = helpers.formatParamValue(pp, imports);
|
|
587
|
-
if (pp.isEncoded) {
|
|
588
|
-
imports.add('net/url');
|
|
589
|
-
paramValue = `url.PathEscape(${helpers.formatParamValue(pp, imports)})`;
|
|
590
|
-
}
|
|
591
|
-
text += `\turlPath = strings.ReplaceAll(urlPath, "{${pp.pathSegment}}", ${paramValue})\n`;
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
text += `\treq, err := runtime.NewRequest(ctx, http.Method${capitalize(method.httpMethod)}, ${hostParam})\n`;
|
|
595
|
-
text += '\tif err != nil {\n';
|
|
596
|
-
text += '\t\treturn nil, err\n';
|
|
597
|
-
text += '\t}\n';
|
|
598
731
|
// helper to build nil checks for param groups
|
|
599
732
|
const emitParamGroupCheck = function (param) {
|
|
600
733
|
if (!param.group) {
|
|
@@ -611,6 +744,81 @@ function createProtocolRequest(azureARM, client, method, imports) {
|
|
|
611
744
|
}
|
|
612
745
|
return `\tif ${optionalParamGroupCheck}${client}${paramGroupName}.${capitalize(param.name)} != nil {\n`;
|
|
613
746
|
};
|
|
747
|
+
if (hasPathParams) {
|
|
748
|
+
// swagger defines path params, emit path and replace tokens
|
|
749
|
+
imports.add('strings');
|
|
750
|
+
// replace path parameters
|
|
751
|
+
for (const pp of methodParamGroups.pathParams) {
|
|
752
|
+
let paramValue;
|
|
753
|
+
let optionalPathSep = false;
|
|
754
|
+
if (pp.style !== 'optional') {
|
|
755
|
+
// emit check to ensure path param isn't an empty string
|
|
756
|
+
if (pp.kind === 'pathScalarParam') {
|
|
757
|
+
const choiceIsString = function (type) {
|
|
758
|
+
return type.kind === 'constant' && type.type === 'string';
|
|
759
|
+
};
|
|
760
|
+
// we only need to do this for params that have an underlying type of string
|
|
761
|
+
if ((pp.type.kind === 'string' || choiceIsString(pp.type)) && !pp.omitEmptyStringCheck) {
|
|
762
|
+
const paramName = helpers.getParamName(pp);
|
|
763
|
+
imports.add('errors');
|
|
764
|
+
text += `\tif ${paramName} == "" {\n`;
|
|
765
|
+
text += `\t\treturn nil, errors.New("parameter ${paramName} cannot be empty")\n`;
|
|
766
|
+
text += '\t}\n';
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
paramValue = helpers.formatParamValue(pp, imports);
|
|
770
|
+
// for collection-based path params, we emit the empty check
|
|
771
|
+
// after calling helpers.formatParamValue as that will have the
|
|
772
|
+
// var name that contains the slice.
|
|
773
|
+
if (pp.kind === 'pathCollectionParam') {
|
|
774
|
+
const paramName = helpers.getParamName(pp);
|
|
775
|
+
const joinedParamName = `${paramName}Param`;
|
|
776
|
+
text += `\t${joinedParamName} := ${paramValue}\n`;
|
|
777
|
+
imports.add('errors');
|
|
778
|
+
text += `\tif len(${joinedParamName}) == 0 {\n`;
|
|
779
|
+
text += `\t\treturn nil, errors.New("parameter ${paramName} cannot be empty")\n`;
|
|
780
|
+
text += '\t}\n';
|
|
781
|
+
paramValue = joinedParamName;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
else {
|
|
785
|
+
// param isn't required, so emit a local var with
|
|
786
|
+
// the correct default value, then populate it with
|
|
787
|
+
// the optional value when set.
|
|
788
|
+
paramValue = `optional${capitalize(pp.name)}`;
|
|
789
|
+
text += `\t${paramValue} := ""\n`;
|
|
790
|
+
text += emitParamGroupCheck(pp);
|
|
791
|
+
text += `\t${paramValue} = ${helpers.formatParamValue(pp, imports)}\n\t}\n`;
|
|
792
|
+
// there are two cases for optional path params.
|
|
793
|
+
// - /foo/bar/{optional}
|
|
794
|
+
// - /foo/bar{/optional}
|
|
795
|
+
// for the second case, we need to include a forward slash
|
|
796
|
+
if (method.httpPath[method.httpPath.indexOf(`{${pp.pathSegment}}`) - 1] !== '/') {
|
|
797
|
+
optionalPathSep = true;
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
const emitPathEscape = function () {
|
|
801
|
+
if (pp.isEncoded) {
|
|
802
|
+
imports.add('net/url');
|
|
803
|
+
return `url.PathEscape(${paramValue})`;
|
|
804
|
+
}
|
|
805
|
+
return paramValue;
|
|
806
|
+
};
|
|
807
|
+
if (optionalPathSep) {
|
|
808
|
+
text += `\tif len(${paramValue}) > 0 {\n`;
|
|
809
|
+
text += `\t\t${paramValue} = "/"+${emitPathEscape()}\n`;
|
|
810
|
+
text += '\t}\n';
|
|
811
|
+
}
|
|
812
|
+
else {
|
|
813
|
+
paramValue = emitPathEscape();
|
|
814
|
+
}
|
|
815
|
+
text += `\turlPath = strings.ReplaceAll(urlPath, "{${pp.pathSegment}}", ${paramValue})\n`;
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
text += `\treq, err := runtime.NewRequest(ctx, http.Method${capitalize(method.httpMethod)}, ${hostParam})\n`;
|
|
819
|
+
text += '\tif err != nil {\n';
|
|
820
|
+
text += '\t\treturn nil, err\n';
|
|
821
|
+
text += '\t}\n';
|
|
614
822
|
// add query parameters
|
|
615
823
|
const encodedParams = methodParamGroups.encodedQueryParams;
|
|
616
824
|
const unencodedParams = methodParamGroups.unencodedQueryParams;
|
|
@@ -619,7 +827,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
|
|
|
619
827
|
if (qp.location === 'method' && go.isClientSideDefault(qp.style)) {
|
|
620
828
|
qpText = emitClientSideDefault(qp, qp.style, (name, val) => { return `\treqQP.Set(${name}, ${val})`; }, imports);
|
|
621
829
|
}
|
|
622
|
-
else if (go.isRequiredParameter(qp) || go.isLiteralParameter(qp) || (qp.location === 'client' && go.isClientSideDefault(qp.style))) {
|
|
830
|
+
else if (go.isRequiredParameter(qp.style) || go.isLiteralParameter(qp.style) || (qp.location === 'client' && go.isClientSideDefault(qp.style))) {
|
|
623
831
|
qpText = `\t${setter}\n`;
|
|
624
832
|
}
|
|
625
833
|
else if (qp.location === 'client' && !qp.group) {
|
|
@@ -697,7 +905,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
|
|
|
697
905
|
imports.add('strings');
|
|
698
906
|
text += '\treq.Raw().URL.RawQuery = strings.Join(unencodedParams, "&")\n';
|
|
699
907
|
}
|
|
700
|
-
if (method.kind !== 'nextPageMethod' && method.
|
|
908
|
+
if (method.kind !== 'nextPageMethod' && method.returns.result?.kind === 'binaryResult') {
|
|
701
909
|
// skip auto-body downloading for binary stream responses
|
|
702
910
|
text += '\truntime.SkipBodyDownload(req)\n';
|
|
703
911
|
}
|
|
@@ -733,7 +941,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
|
|
|
733
941
|
// we do it like this as tsp specifies content-type while swagger does not.
|
|
734
942
|
contentType = helpers.formatParamValue(param, imports);
|
|
735
943
|
}
|
|
736
|
-
else if (go.isRequiredParameter(param) || go.isLiteralParameter(param) || go.isClientSideDefault(param.style)) {
|
|
944
|
+
else if (go.isRequiredParameter(param.style) || go.isLiteralParameter(param.style) || go.isClientSideDefault(param.style)) {
|
|
737
945
|
text += emitHeaderSet(param, '\t');
|
|
738
946
|
}
|
|
739
947
|
else if (param.location === 'client' && !param.group) {
|
|
@@ -785,7 +993,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
|
|
|
785
993
|
text += `\t\t${fieldName} *${go.getTypeDeclaration(bodyParam.type)} \`xml:"${tag}"\`\n`;
|
|
786
994
|
text += '\t}\n';
|
|
787
995
|
let addr = '&';
|
|
788
|
-
if (!go.isRequiredParameter(bodyParam) && !bodyParam.byValue) {
|
|
996
|
+
if (!go.isRequiredParameter(bodyParam.style) && !bodyParam.byValue) {
|
|
789
997
|
addr = '';
|
|
790
998
|
}
|
|
791
999
|
body = `wrapper{${fieldName}: ${addr}${body}}`;
|
|
@@ -821,7 +1029,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
|
|
|
821
1029
|
imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming');
|
|
822
1030
|
setBody = `req.SetBody(streaming.NopCloser(bytes.NewReader(${body})), "application/${bodyParam.bodyFormat.toLowerCase()}")`;
|
|
823
1031
|
}
|
|
824
|
-
if (go.isRequiredParameter(bodyParam) || go.isLiteralParameter(bodyParam)) {
|
|
1032
|
+
if (go.isRequiredParameter(bodyParam.style) || go.isLiteralParameter(bodyParam.style)) {
|
|
825
1033
|
text += `\t${emitSetBodyWithErrCheck(setBody, contentType)}`;
|
|
826
1034
|
text += '\treturn req, nil\n';
|
|
827
1035
|
}
|
|
@@ -834,7 +1042,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
|
|
|
834
1042
|
}
|
|
835
1043
|
}
|
|
836
1044
|
else if (bodyParam.bodyFormat === 'binary') {
|
|
837
|
-
if (go.isRequiredParameter(bodyParam)) {
|
|
1045
|
+
if (go.isRequiredParameter(bodyParam.style)) {
|
|
838
1046
|
text += `\t${emitSetBodyWithErrCheck(`req.SetBody(${bodyParam.name}, ${bodyParam.contentType})`, contentType)}`;
|
|
839
1047
|
text += '\treturn req, nil\n';
|
|
840
1048
|
}
|
|
@@ -849,7 +1057,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
|
|
|
849
1057
|
else if (bodyParam.bodyFormat === 'Text') {
|
|
850
1058
|
imports.add('strings');
|
|
851
1059
|
imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming');
|
|
852
|
-
if (go.isRequiredParameter(bodyParam)) {
|
|
1060
|
+
if (go.isRequiredParameter(bodyParam.style)) {
|
|
853
1061
|
text += `\tbody := streaming.NopCloser(strings.NewReader(${bodyParam.name}))\n`;
|
|
854
1062
|
text += `\t${emitSetBodyWithErrCheck(`req.SetBody(body, ${bodyParam.contentType})`, contentType)}`;
|
|
855
1063
|
text += '\treturn req, nil\n';
|
|
@@ -869,19 +1077,19 @@ function createProtocolRequest(azureARM, client, method, imports) {
|
|
|
869
1077
|
// define and instantiate an instance of the wire type, using the values from each param.
|
|
870
1078
|
text += '\tbody := struct {\n';
|
|
871
1079
|
for (const partialBodyParam of partialBodyParams) {
|
|
872
|
-
text += `\t\t${capitalize(partialBodyParam.serializedName)} ${helpers.star(partialBodyParam)}${go.getTypeDeclaration(partialBodyParam.type)} \`${partialBodyParam.format.toLowerCase()}:"${partialBodyParam.serializedName}"\`\n`;
|
|
1080
|
+
text += `\t\t${capitalize(partialBodyParam.serializedName)} ${helpers.star(partialBodyParam.byValue)}${go.getTypeDeclaration(partialBodyParam.type)} \`${partialBodyParam.format.toLowerCase()}:"${partialBodyParam.serializedName}"\`\n`;
|
|
873
1081
|
}
|
|
874
1082
|
text += '\t}{\n';
|
|
875
1083
|
// required params are emitted as initializers in the struct literal
|
|
876
1084
|
for (const partialBodyParam of partialBodyParams) {
|
|
877
|
-
if (go.isRequiredParameter(partialBodyParam)) {
|
|
1085
|
+
if (go.isRequiredParameter(partialBodyParam.style)) {
|
|
878
1086
|
text += `\t\t${capitalize(partialBodyParam.serializedName)}: ${uncapitalize(partialBodyParam.name)},\n`;
|
|
879
1087
|
}
|
|
880
1088
|
}
|
|
881
1089
|
text += '\t}\n';
|
|
882
1090
|
// now populate any optional params from the options type
|
|
883
1091
|
for (const partialBodyParam of partialBodyParams) {
|
|
884
|
-
if (!go.isRequiredParameter(partialBodyParam)) {
|
|
1092
|
+
if (!go.isRequiredParameter(partialBodyParam.style)) {
|
|
885
1093
|
text += emitParamGroupCheck(partialBodyParam);
|
|
886
1094
|
text += `\t\tbody.${capitalize(partialBodyParam.serializedName)} = options.${capitalize(partialBodyParam.name)}\n\t}\n`;
|
|
887
1095
|
}
|
|
@@ -900,7 +1108,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
|
|
|
900
1108
|
text += '\tformData := map[string]any{}\n';
|
|
901
1109
|
for (const param of multipartBodyParams) {
|
|
902
1110
|
const setter = `formData["${param.name}"] = ${helpers.getParamName(param)}`;
|
|
903
|
-
if (go.isRequiredParameter(param)) {
|
|
1111
|
+
if (go.isRequiredParameter(param.style)) {
|
|
904
1112
|
text += `\t${setter}\n`;
|
|
905
1113
|
}
|
|
906
1114
|
else {
|
|
@@ -915,7 +1123,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
|
|
|
915
1123
|
else if (formBodyParams.length > 0) {
|
|
916
1124
|
const emitFormData = function (param, setter) {
|
|
917
1125
|
let formDataText = '';
|
|
918
|
-
if (go.isRequiredParameter(param)) {
|
|
1126
|
+
if (go.isRequiredParameter(param.style)) {
|
|
919
1127
|
formDataText = `\t${setter}\n`;
|
|
920
1128
|
}
|
|
921
1129
|
else {
|
|
@@ -997,7 +1205,7 @@ function isArrayOfDateTimeForMarshalling(paramType) {
|
|
|
997
1205
|
// returns true if the method requires a response handler.
|
|
998
1206
|
// this is used to unmarshal the response body, parse response headers, or both.
|
|
999
1207
|
function needsResponseHandler(method) {
|
|
1000
|
-
return helpers.hasSchemaResponse(method) || method.
|
|
1208
|
+
return helpers.hasSchemaResponse(method) || method.returns.headers.length > 0;
|
|
1001
1209
|
}
|
|
1002
1210
|
function generateResponseUnmarshaller(method, type, format, unmarshalTarget) {
|
|
1003
1211
|
let unmarshallerText = '';
|
|
@@ -1065,34 +1273,34 @@ function generateResponseUnmarshaller(method, type, format, unmarshalTarget) {
|
|
|
1065
1273
|
}
|
|
1066
1274
|
else {
|
|
1067
1275
|
// the remaining formats should have been handled elsewhere
|
|
1068
|
-
throw new CodegenError('InternalError', `unhandled format ${format} for operation ${method.
|
|
1276
|
+
throw new CodegenError('InternalError', `unhandled format ${format} for operation ${method.receiver.type.name}.${method.name}`);
|
|
1069
1277
|
}
|
|
1070
1278
|
return unmarshallerText;
|
|
1071
1279
|
}
|
|
1072
|
-
function createProtocolResponse(
|
|
1280
|
+
function createProtocolResponse(method, imports) {
|
|
1073
1281
|
if (!needsResponseHandler(method)) {
|
|
1074
1282
|
return '';
|
|
1075
1283
|
}
|
|
1076
1284
|
const name = method.naming.responseMethod;
|
|
1077
1285
|
let text = `${comment(name, '// ')} handles the ${method.name} response.\n`;
|
|
1078
|
-
text += `func (
|
|
1286
|
+
text += `func ${getClientReceiverDefinition(method.receiver)} ${name}(resp *http.Response) (${generateReturnsInfo(method, 'handler').join(', ')}) {\n`;
|
|
1079
1287
|
const addHeaders = function (headers) {
|
|
1080
1288
|
for (const header of values(headers)) {
|
|
1081
|
-
text += formatHeaderResponseValue(header, imports, 'result', `${method.
|
|
1289
|
+
text += formatHeaderResponseValue(header, imports, 'result', `${method.returns.name}{}`);
|
|
1082
1290
|
}
|
|
1083
1291
|
};
|
|
1084
|
-
const result = method.
|
|
1292
|
+
const result = method.returns.result;
|
|
1085
1293
|
if (!result) {
|
|
1086
1294
|
// only headers
|
|
1087
|
-
text += `\tresult := ${method.
|
|
1088
|
-
addHeaders(method.
|
|
1295
|
+
text += `\tresult := ${method.returns.name}{}\n`;
|
|
1296
|
+
addHeaders(method.returns.headers);
|
|
1089
1297
|
}
|
|
1090
1298
|
else {
|
|
1091
1299
|
switch (result.kind) {
|
|
1092
1300
|
case 'anyResult':
|
|
1093
1301
|
imports.add('fmt');
|
|
1094
|
-
text += `\tresult := ${method.
|
|
1095
|
-
addHeaders(method.
|
|
1302
|
+
text += `\tresult := ${method.returns.name}{}\n`;
|
|
1303
|
+
addHeaders(method.returns.headers);
|
|
1096
1304
|
text += '\tswitch resp.StatusCode {\n';
|
|
1097
1305
|
for (const statusCode of method.httpStatusCodes) {
|
|
1098
1306
|
text += `\tcase ${helpers.formatStatusCodes([statusCode])}:\n`;
|
|
@@ -1110,21 +1318,21 @@ function createProtocolResponse(client, method, imports) {
|
|
|
1110
1318
|
text += '\t}\n';
|
|
1111
1319
|
break;
|
|
1112
1320
|
case 'binaryResult':
|
|
1113
|
-
text += `\tresult := ${method.
|
|
1114
|
-
addHeaders(method.
|
|
1321
|
+
text += `\tresult := ${method.returns.name}{${result.fieldName}: resp.Body}\n`;
|
|
1322
|
+
addHeaders(method.returns.headers);
|
|
1115
1323
|
break;
|
|
1116
1324
|
case 'headAsBooleanResult':
|
|
1117
|
-
text += `\tresult := ${method.
|
|
1118
|
-
addHeaders(method.
|
|
1325
|
+
text += `\tresult := ${method.returns.name}{${result.fieldName}: resp.StatusCode >= 200 && resp.StatusCode < 300}\n`;
|
|
1326
|
+
addHeaders(method.returns.headers);
|
|
1119
1327
|
break;
|
|
1120
1328
|
case 'modelResult':
|
|
1121
|
-
text += `\tresult := ${method.
|
|
1122
|
-
addHeaders(method.
|
|
1329
|
+
text += `\tresult := ${method.returns.name}{}\n`;
|
|
1330
|
+
addHeaders(method.returns.headers);
|
|
1123
1331
|
text += generateResponseUnmarshaller(method, result.modelType, result.format, `result.${helpers.getResultFieldName(method)}`);
|
|
1124
1332
|
break;
|
|
1125
1333
|
case 'monomorphicResult':
|
|
1126
|
-
text += `\tresult := ${method.
|
|
1127
|
-
addHeaders(method.
|
|
1334
|
+
text += `\tresult := ${method.returns.name}{}\n`;
|
|
1335
|
+
addHeaders(method.returns.headers);
|
|
1128
1336
|
let target = `result.${helpers.getResultFieldName(method)}`;
|
|
1129
1337
|
// when unmarshalling a wrapped XML array, unmarshal into the response envelope
|
|
1130
1338
|
if (result.format === 'XML' && result.monomorphicType.kind === 'slice') {
|
|
@@ -1133,8 +1341,8 @@ function createProtocolResponse(client, method, imports) {
|
|
|
1133
1341
|
text += generateResponseUnmarshaller(method, result.monomorphicType, result.format, target);
|
|
1134
1342
|
break;
|
|
1135
1343
|
case 'polymorphicResult':
|
|
1136
|
-
text += `\tresult := ${method.
|
|
1137
|
-
addHeaders(method.
|
|
1344
|
+
text += `\tresult := ${method.returns.name}{}\n`;
|
|
1345
|
+
addHeaders(method.returns.headers);
|
|
1138
1346
|
text += generateResponseUnmarshaller(method, result.interface, result.format, 'result');
|
|
1139
1347
|
break;
|
|
1140
1348
|
default:
|
|
@@ -1187,7 +1395,7 @@ function getAPIParametersSig(method, imports, pkgName) {
|
|
|
1187
1395
|
// op - for the operation
|
|
1188
1396
|
// handler - for the response handler
|
|
1189
1397
|
function generateReturnsInfo(method, apiType) {
|
|
1190
|
-
let returnType = method.
|
|
1398
|
+
let returnType = method.returns.name;
|
|
1191
1399
|
switch (method.kind) {
|
|
1192
1400
|
case 'lroMethod':
|
|
1193
1401
|
case 'lroPageableMethod':
|
|
@@ -1222,7 +1430,7 @@ function generateReturnsInfo(method, apiType) {
|
|
|
1222
1430
|
}
|
|
1223
1431
|
return [returnType, 'error'];
|
|
1224
1432
|
}
|
|
1225
|
-
function generateLROBeginMethod(
|
|
1433
|
+
function generateLROBeginMethod(method, imports, injectSpans, generateFakes) {
|
|
1226
1434
|
const params = getAPIParametersSig(method, imports);
|
|
1227
1435
|
const returns = generateReturnsInfo(method, 'api');
|
|
1228
1436
|
imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
|
|
@@ -1237,15 +1445,15 @@ function generateLROBeginMethod(client, method, imports, injectSpans, generateFa
|
|
|
1237
1445
|
for (const param of values(methodParams)) {
|
|
1238
1446
|
text += helpers.formatCommentAsBulletItem(param.name, param.docs);
|
|
1239
1447
|
}
|
|
1240
|
-
text += `func (
|
|
1448
|
+
text += `func ${getClientReceiverDefinition(method.receiver)} ${fixUpMethodName(method)}(${params}) (${returns.join(', ')}) {\n`;
|
|
1241
1449
|
let pollerType = 'nil';
|
|
1242
|
-
let pollerTypeParam = `[${method.
|
|
1450
|
+
let pollerTypeParam = `[${method.returns.name}]`;
|
|
1243
1451
|
if (method.kind === 'lroPageableMethod') {
|
|
1244
1452
|
// for paged LROs, we construct a pager and pass it to the LRO ctor.
|
|
1245
1453
|
pollerTypeParam = `[*runtime.Pager${pollerTypeParam}]`;
|
|
1246
1454
|
pollerType = '&pager';
|
|
1247
1455
|
text += '\tpager := ';
|
|
1248
|
-
text += emitPagerDefinition(
|
|
1456
|
+
text += emitPagerDefinition(method, imports, injectSpans, generateFakes);
|
|
1249
1457
|
}
|
|
1250
1458
|
text += '\tif options == nil || options.ResumeToken == "" {\n';
|
|
1251
1459
|
// creating the poller from response branch
|