@azure-tools/typespec-ts 0.30.1 → 0.31.0-alpha.20240723.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/src/contextManager.d.ts +4 -0
- package/dist/src/contextManager.d.ts.map +1 -1
- package/dist/src/contextManager.js.map +1 -1
- package/dist/src/framework/declaration.d.ts +9 -0
- package/dist/src/framework/declaration.d.ts.map +1 -0
- package/dist/src/framework/declaration.js +28 -0
- package/dist/src/framework/declaration.js.map +1 -0
- package/dist/src/framework/hooks/binder.d.ts +25 -0
- package/dist/src/framework/hooks/binder.d.ts.map +1 -0
- package/dist/src/framework/hooks/binder.js +168 -0
- package/dist/src/framework/hooks/binder.js.map +1 -0
- package/dist/src/framework/hooks/sdkTypes.d.ts +12 -0
- package/dist/src/framework/hooks/sdkTypes.d.ts.map +1 -0
- package/dist/src/framework/hooks/sdkTypes.js +67 -0
- package/dist/src/framework/hooks/sdkTypes.js.map +1 -0
- package/dist/src/framework/reference.d.ts +2 -0
- package/dist/src/framework/reference.d.ts.map +1 -0
- package/dist/src/framework/reference.js +8 -0
- package/dist/src/framework/reference.js.map +1 -0
- package/dist/src/framework/refkey.d.ts +7 -0
- package/dist/src/framework/refkey.d.ts.map +1 -0
- package/dist/src/framework/refkey.js +22 -0
- package/dist/src/framework/refkey.js.map +1 -0
- package/dist/src/framework/sample.d.ts +2 -0
- package/dist/src/framework/sample.d.ts.map +1 -0
- package/dist/src/framework/sample.js +71 -0
- package/dist/src/framework/sample.js.map +1 -0
- package/dist/src/framework/utils/tsmorph-helpers.d.ts +2 -0
- package/dist/src/framework/utils/tsmorph-helpers.d.ts.map +1 -0
- package/dist/src/framework/utils/tsmorph-helpers.js +2 -0
- package/dist/src/framework/utils/tsmorph-helpers.js.map +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -8
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib.d.ts +10 -1
- package/dist/src/lib.d.ts.map +1 -1
- package/dist/src/lib.js +6 -0
- package/dist/src/lib.js.map +1 -1
- package/dist/src/modular/buildClassicalClient.d.ts.map +1 -1
- package/dist/src/modular/buildClassicalClient.js +6 -5
- package/dist/src/modular/buildClassicalClient.js.map +1 -1
- package/dist/src/modular/buildClientContext.d.ts.map +1 -1
- package/dist/src/modular/buildClientContext.js +8 -4
- package/dist/src/modular/buildClientContext.js.map +1 -1
- package/dist/src/modular/buildCodeModel.d.ts.map +1 -1
- package/dist/src/modular/buildCodeModel.js +22 -11
- package/dist/src/modular/buildCodeModel.js.map +1 -1
- package/dist/src/modular/buildOperations.d.ts +1 -2
- package/dist/src/modular/buildOperations.d.ts.map +1 -1
- package/dist/src/modular/buildOperations.js +3 -9
- package/dist/src/modular/buildOperations.js.map +1 -1
- package/dist/src/modular/buildRootIndex.js +1 -1
- package/dist/src/modular/buildRootIndex.js.map +1 -1
- package/dist/src/modular/buildSerializeUtils.d.ts.map +1 -1
- package/dist/src/modular/buildSerializeUtils.js +2 -1
- package/dist/src/modular/buildSerializeUtils.js.map +1 -1
- package/dist/src/modular/helpers/clientHelpers.d.ts +4 -0
- package/dist/src/modular/helpers/clientHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/clientHelpers.js +15 -1
- package/dist/src/modular/helpers/clientHelpers.js.map +1 -1
- package/dist/src/modular/helpers/namingHelpers.d.ts +1 -0
- package/dist/src/modular/helpers/namingHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/namingHelpers.js +3 -1
- package/dist/src/modular/helpers/namingHelpers.js.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.js +60 -40
- package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
- package/dist/src/modular/helpers/typeHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/typeHelpers.js +6 -1
- package/dist/src/modular/helpers/typeHelpers.js.map +1 -1
- package/dist/src/modular/modularCodeModel.d.ts +2 -0
- package/dist/src/modular/modularCodeModel.d.ts.map +1 -1
- package/dist/src/transform/transformApiVersionInfo.d.ts.map +1 -1
- package/dist/src/transform/transformApiVersionInfo.js +3 -5
- package/dist/src/transform/transformApiVersionInfo.js.map +1 -1
- package/dist/src/transform/transformHelperFunctionDetails.d.ts.map +1 -1
- package/dist/src/transform/transformHelperFunctionDetails.js +7 -10
- package/dist/src/transform/transformHelperFunctionDetails.js.map +1 -1
- package/dist/src/transform/transformParameters.d.ts.map +1 -1
- package/dist/src/transform/transformParameters.js +5 -7
- package/dist/src/transform/transformParameters.js.map +1 -1
- package/dist/src/transform/transformPaths.d.ts.map +1 -1
- package/dist/src/transform/transformPaths.js +4 -6
- package/dist/src/transform/transformPaths.js.map +1 -1
- package/dist/src/transform/transformResponses.d.ts.map +1 -1
- package/dist/src/transform/transformResponses.js +70 -16
- package/dist/src/transform/transformResponses.js.map +1 -1
- package/dist/src/transform/transformSchemas.d.ts.map +1 -1
- package/dist/src/transform/transformSchemas.js +5 -6
- package/dist/src/transform/transformSchemas.js.map +1 -1
- package/dist/src/transform/transformTelemetryInfo.d.ts.map +1 -1
- package/dist/src/transform/transformTelemetryInfo.js +3 -6
- package/dist/src/transform/transformTelemetryInfo.js.map +1 -1
- package/dist/src/transform/transfromRLCOptions.d.ts.map +1 -1
- package/dist/src/transform/transfromRLCOptions.js +5 -6
- package/dist/src/transform/transfromRLCOptions.js.map +1 -1
- package/dist/src/utils/modelUtils.d.ts +3 -3
- package/dist/src/utils/modelUtils.d.ts.map +1 -1
- package/dist/src/utils/modelUtils.js +42 -24
- package/dist/src/utils/modelUtils.js.map +1 -1
- package/dist/src/utils/operationUtil.d.ts +2 -2
- package/dist/src/utils/operationUtil.d.ts.map +1 -1
- package/dist/src/utils/operationUtil.js +5 -7
- package/dist/src/utils/operationUtil.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +23 -23
- package/src/contextManager.ts +4 -0
- package/src/framework/declaration.ts +100 -0
- package/src/framework/hooks/binder.ts +259 -0
- package/src/framework/hooks/sdkTypes.ts +101 -0
- package/src/framework/reference.ts +9 -0
- package/src/framework/refkey.ts +28 -0
- package/src/framework/sample.ts +92 -0
- package/src/framework/utils/tsmorph-helpers.ts +0 -0
- package/src/index.ts +8 -10
- package/src/lib.ts +6 -0
- package/src/modular/buildClassicalClient.ts +11 -4
- package/src/modular/buildClientContext.ts +11 -5
- package/src/modular/buildCodeModel.ts +25 -21
- package/src/modular/buildOperations.ts +13 -41
- package/src/modular/buildRootIndex.ts +1 -1
- package/src/modular/buildSerializeUtils.ts +2 -1
- package/src/modular/helpers/clientHelpers.ts +25 -1
- package/src/modular/helpers/namingHelpers.ts +4 -1
- package/src/modular/helpers/operationHelpers.ts +86 -45
- package/src/modular/helpers/typeHelpers.ts +6 -1
- package/src/modular/modularCodeModel.ts +2 -0
- package/src/transform/transformApiVersionInfo.ts +3 -6
- package/src/transform/transformHelperFunctionDetails.ts +9 -9
- package/src/transform/transformParameters.ts +5 -6
- package/src/transform/transformPaths.ts +5 -9
- package/src/transform/transformResponses.ts +92 -19
- package/src/transform/transformSchemas.ts +6 -5
- package/src/transform/transformTelemetryInfo.ts +3 -5
- package/src/transform/transfromRLCOptions.ts +5 -10
- package/src/utils/modelUtils.ts +49 -39
- package/src/utils/operationUtil.ts +6 -12
- package/dist/src/modular/serialization/collectionUtils.d.ts +0 -3
- package/dist/src/modular/serialization/collectionUtils.d.ts.map +0 -1
- package/dist/src/modular/serialization/collectionUtils.js +0 -17
- package/dist/src/modular/serialization/collectionUtils.js.map +0 -1
- package/dist/src/modular/serialization/index.d.ts +0 -5
- package/dist/src/modular/serialization/index.d.ts.map +0 -1
- package/dist/src/modular/serialization/index.js +0 -155
- package/dist/src/modular/serialization/index.js.map +0 -1
- package/dist/src/modular/serialization/operationHelpers.d.ts +0 -37
- package/dist/src/modular/serialization/operationHelpers.d.ts.map +0 -1
- package/dist/src/modular/serialization/operationHelpers.js +0 -457
- package/dist/src/modular/serialization/operationHelpers.js.map +0 -1
- package/dist/src/modular/serialization/serializeArray.d.ts +0 -5
- package/dist/src/modular/serialization/serializeArray.d.ts.map +0 -1
- package/dist/src/modular/serialization/serializeArray.js +0 -33
- package/dist/src/modular/serialization/serializeArray.js.map +0 -1
- package/dist/src/modular/serialization/serializeDateTime.d.ts +0 -4
- package/dist/src/modular/serialization/serializeDateTime.d.ts.map +0 -1
- package/dist/src/modular/serialization/serializeDateTime.js +0 -19
- package/dist/src/modular/serialization/serializeDateTime.js.map +0 -1
- package/dist/src/modular/serialization/serializeHeaders.d.ts +0 -7
- package/dist/src/modular/serialization/serializeHeaders.d.ts.map +0 -1
- package/dist/src/modular/serialization/serializeHeaders.js +0 -44
- package/dist/src/modular/serialization/serializeHeaders.js.map +0 -1
- package/dist/src/modular/serialization/serializers.d.ts +0 -17
- package/dist/src/modular/serialization/serializers.d.ts.map +0 -1
- package/dist/src/modular/serialization/serializers.js +0 -175
- package/dist/src/modular/serialization/serializers.js.map +0 -1
- package/dist/src/modular/serialization/util.d.ts +0 -27
- package/dist/src/modular/serialization/util.d.ts.map +0 -1
- package/dist/src/modular/serialization/util.js +0 -115
- package/dist/src/modular/serialization/util.js.map +0 -1
- package/dist/src/reify/index.d.ts +0 -12
- package/dist/src/reify/index.d.ts.map +0 -1
- package/dist/src/reify/index.js +0 -22
- package/dist/src/reify/index.js.map +0 -1
- package/src/modular/serialization/collectionUtils.ts +0 -20
- package/src/modular/serialization/index.ts +0 -267
- package/src/modular/serialization/operationHelpers.ts +0 -659
- package/src/modular/serialization/serializeArray.ts +0 -51
- package/src/modular/serialization/serializeDateTime.ts +0 -22
- package/src/modular/serialization/serializeHeaders.ts +0 -64
- package/src/modular/serialization/serializers.ts +0 -304
- package/src/modular/serialization/util.ts +0 -171
- package/src/modular/static/karma.conf.cjs +0 -120
- package/src/reify/index.ts +0 -41
|
@@ -1,659 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
addImportToSpecifier,
|
|
3
|
-
getResponseBaseName,
|
|
4
|
-
getResponseTypeName,
|
|
5
|
-
Imports as RuntimeImports,
|
|
6
|
-
NameType,
|
|
7
|
-
OperationResponse
|
|
8
|
-
} from "@azure-tools/rlc-common";
|
|
9
|
-
import { SdkContext } from "@azure-tools/typespec-client-generator-core";
|
|
10
|
-
import {
|
|
11
|
-
FunctionDeclarationStructure,
|
|
12
|
-
OptionalKind,
|
|
13
|
-
ParameterDeclarationStructure
|
|
14
|
-
} from "ts-morph";
|
|
15
|
-
|
|
16
|
-
import { toPascalCase } from "../../utils/casingUtils.js";
|
|
17
|
-
import {
|
|
18
|
-
getDocsFromDescription,
|
|
19
|
-
getFixmeForMultilineDocs
|
|
20
|
-
} from "../helpers/docsHelpers.js";
|
|
21
|
-
import {
|
|
22
|
-
getClassicalLayerPrefix,
|
|
23
|
-
getOperationName
|
|
24
|
-
} from "../helpers/namingHelpers.js";
|
|
25
|
-
import { buildType } from "../helpers/typeHelpers.js";
|
|
26
|
-
import {
|
|
27
|
-
BodyParameter,
|
|
28
|
-
Client,
|
|
29
|
-
ModularCodeModel,
|
|
30
|
-
Operation,
|
|
31
|
-
ParameterLocation,
|
|
32
|
-
Property,
|
|
33
|
-
Type
|
|
34
|
-
} from "../modularCodeModel.js";
|
|
35
|
-
|
|
36
|
-
import { UsageFlags } from "@typespec/compiler";
|
|
37
|
-
import _ from "lodash";
|
|
38
|
-
import { Parameter } from "../modularCodeModel.js";
|
|
39
|
-
import { serializeType } from "../serialization/serializers.js";
|
|
40
|
-
import { SerializerMap, isDefined } from "../serialization/util.js";
|
|
41
|
-
|
|
42
|
-
export function getRLCResponseType(rlcResponse?: OperationResponse) {
|
|
43
|
-
if (!rlcResponse?.responses) {
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
return rlcResponse?.responses
|
|
47
|
-
.map((resp) => {
|
|
48
|
-
const baseResponseName = getResponseBaseName(
|
|
49
|
-
rlcResponse.operationGroup,
|
|
50
|
-
rlcResponse.operationName,
|
|
51
|
-
resp.statusCode
|
|
52
|
-
);
|
|
53
|
-
// Get the information to build the Response Interface
|
|
54
|
-
return resp.predefinedName ?? getResponseTypeName(baseResponseName);
|
|
55
|
-
})
|
|
56
|
-
.join(" | ");
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export function getRLCLroLogicalResponse(rlcResponse?: OperationResponse) {
|
|
60
|
-
const logicalResponse = (rlcResponse?.responses ?? []).filter(
|
|
61
|
-
(r) => r.predefinedName && r.predefinedName.endsWith(`LogicalResponse`)
|
|
62
|
-
);
|
|
63
|
-
return logicalResponse.length > 0
|
|
64
|
-
? logicalResponse[0]!.predefinedName!
|
|
65
|
-
: "any";
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export function getSendPrivateFunction(
|
|
69
|
-
dpgContext: SdkContext,
|
|
70
|
-
operation: Operation,
|
|
71
|
-
clientType: string,
|
|
72
|
-
serializerMap: SerializerMap | undefined,
|
|
73
|
-
runtimeImports: RuntimeImports
|
|
74
|
-
): OptionalKind<FunctionDeclarationStructure> {
|
|
75
|
-
const parameters = getOperationSignatureParameters(operation, clientType);
|
|
76
|
-
const { name } = getOperationName(operation);
|
|
77
|
-
const returnType = `StreamableMethod<${getRLCResponseType(
|
|
78
|
-
operation.rlcResponse
|
|
79
|
-
)}>`;
|
|
80
|
-
|
|
81
|
-
const functionStatement: OptionalKind<FunctionDeclarationStructure> = {
|
|
82
|
-
isAsync: false,
|
|
83
|
-
isExported: true,
|
|
84
|
-
name: `_${name}Send`,
|
|
85
|
-
parameters,
|
|
86
|
-
returnType
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const operationPath = operation.url;
|
|
90
|
-
const operationMethod = operation.method.toLowerCase();
|
|
91
|
-
const optionalParamName = parameters.filter(
|
|
92
|
-
(p) => p.type?.toString().endsWith("OptionalParams")
|
|
93
|
-
)[0]?.name;
|
|
94
|
-
|
|
95
|
-
const statements: string[] = [];
|
|
96
|
-
statements.push(
|
|
97
|
-
`return context.path("${operationPath}", ${getPathParameters(
|
|
98
|
-
operation
|
|
99
|
-
)}).${operationMethod}({...operationOptionsToRequestParameters(${optionalParamName}), ${getRequestParameters(
|
|
100
|
-
dpgContext,
|
|
101
|
-
operation,
|
|
102
|
-
serializerMap!,
|
|
103
|
-
runtimeImports
|
|
104
|
-
)}}) ${operation.isOverload ? `as ${returnType}` : ``} ;`
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
return {
|
|
108
|
-
...functionStatement,
|
|
109
|
-
statements
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export function getDeserializePrivateFunction(
|
|
114
|
-
dpgContext: SdkContext,
|
|
115
|
-
operation: Operation,
|
|
116
|
-
needSubClient: boolean,
|
|
117
|
-
needUnexpectedHelper: boolean,
|
|
118
|
-
runtimeImports: RuntimeImports,
|
|
119
|
-
serializerMap: SerializerMap | undefined
|
|
120
|
-
): OptionalKind<FunctionDeclarationStructure> {
|
|
121
|
-
const { name } = getOperationName(operation);
|
|
122
|
-
const parameters: OptionalKind<ParameterDeclarationStructure>[] = [
|
|
123
|
-
{
|
|
124
|
-
name: "result",
|
|
125
|
-
type: getRLCResponseType(operation.rlcResponse)
|
|
126
|
-
}
|
|
127
|
-
];
|
|
128
|
-
// TODO: Support LRO + paging operation
|
|
129
|
-
// https://github.com/Azure/autorest.typescript/issues/2313
|
|
130
|
-
const isLroOnly = isLroOnlyOperation(operation);
|
|
131
|
-
|
|
132
|
-
// TODO: Support operation overloads
|
|
133
|
-
const response = operation.responses[0]!;
|
|
134
|
-
let returnType;
|
|
135
|
-
if (isLroOnly && operation.method.toLowerCase() !== "patch") {
|
|
136
|
-
returnType = buildLroReturnType(operation);
|
|
137
|
-
} else if (response?.type?.type) {
|
|
138
|
-
returnType = buildType(
|
|
139
|
-
response.type.name,
|
|
140
|
-
response.type,
|
|
141
|
-
response.type.format
|
|
142
|
-
);
|
|
143
|
-
} else {
|
|
144
|
-
returnType = { name: "", type: "void" };
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
const functionStatement: OptionalKind<FunctionDeclarationStructure> = {
|
|
148
|
-
isAsync: true,
|
|
149
|
-
isExported: true,
|
|
150
|
-
name: `_${name}Deserialize`,
|
|
151
|
-
parameters,
|
|
152
|
-
returnType: `Promise<${returnType.type}>`
|
|
153
|
-
};
|
|
154
|
-
const statements: string[] = [];
|
|
155
|
-
if (needUnexpectedHelper) {
|
|
156
|
-
statements.push(
|
|
157
|
-
`if(${needSubClient ? "UnexpectedHelper." : ""}isUnexpected(result)){`,
|
|
158
|
-
`throw createRestError(result);`,
|
|
159
|
-
"}"
|
|
160
|
-
);
|
|
161
|
-
addImportToSpecifier("restClient", runtimeImports, "createRestError");
|
|
162
|
-
} else {
|
|
163
|
-
const validStatus = [
|
|
164
|
-
...new Set(
|
|
165
|
-
operation.responses
|
|
166
|
-
.flatMap((r) => r.statusCodes)
|
|
167
|
-
.filter((s) => s !== "default")
|
|
168
|
-
)
|
|
169
|
-
];
|
|
170
|
-
|
|
171
|
-
if (validStatus.length > 0) {
|
|
172
|
-
statements.push(
|
|
173
|
-
`if(${validStatus
|
|
174
|
-
.map((s) => `result.status !== "${s}"`)
|
|
175
|
-
.join(" || ")}){`,
|
|
176
|
-
`throw createRestError(result);`,
|
|
177
|
-
"}"
|
|
178
|
-
);
|
|
179
|
-
addImportToSpecifier("restClient", runtimeImports, "createRestError");
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
let deserializedType = isLroOnly
|
|
184
|
-
? operation?.lroMetadata?.finalResult
|
|
185
|
-
: response?.type ?? "void"; // Is setting void here correct? We are handling the case where no response above but here we are
|
|
186
|
-
let hasLroSubPath = operation?.lroMetadata?.finalResultPath !== undefined;
|
|
187
|
-
let deserializedRoot = hasLroSubPath
|
|
188
|
-
? `result.body.${operation?.lroMetadata?.finalResultPath}`
|
|
189
|
-
: "result.body";
|
|
190
|
-
// TODO: Hard-coded for LRO PATCH case for now
|
|
191
|
-
// https://github.com/Azure/autorest.typescript/issues/2314
|
|
192
|
-
if (isLroOnly && operation.method.toLowerCase() === "patch") {
|
|
193
|
-
deserializedType = response.type;
|
|
194
|
-
hasLroSubPath = false;
|
|
195
|
-
deserializedRoot = "result.body";
|
|
196
|
-
}
|
|
197
|
-
if (isLroOnly) {
|
|
198
|
-
const lroLogicalResponse = getRLCLroLogicalResponse(operation.rlcResponse);
|
|
199
|
-
statements.push(`result = result as ${lroLogicalResponse};`);
|
|
200
|
-
if (hasLroSubPath) {
|
|
201
|
-
statements.push(
|
|
202
|
-
`if(${deserializedRoot.split(".").join("?.")} === undefined) {
|
|
203
|
-
throw createRestError(\`Expected a result in the response at position "${deserializedRoot}"\`, result);
|
|
204
|
-
}
|
|
205
|
-
`
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (isDefined(deserializedType?.tcgcType)) {
|
|
211
|
-
statements.push(
|
|
212
|
-
`return ${deserializeResponseValue(
|
|
213
|
-
dpgContext,
|
|
214
|
-
serializerMap!,
|
|
215
|
-
deserializedType,
|
|
216
|
-
deserializedRoot,
|
|
217
|
-
runtimeImports
|
|
218
|
-
)}`
|
|
219
|
-
);
|
|
220
|
-
} else if (returnType.type === "void") {
|
|
221
|
-
statements.push("return");
|
|
222
|
-
} else {
|
|
223
|
-
statements.push(`return result.body`);
|
|
224
|
-
}
|
|
225
|
-
return {
|
|
226
|
-
...functionStatement,
|
|
227
|
-
statements
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
export function getOperationSignatureParameters(
|
|
232
|
-
operation: Operation,
|
|
233
|
-
clientType: string
|
|
234
|
-
): OptionalKind<ParameterDeclarationStructure>[] {
|
|
235
|
-
const optionsType = getOperationOptionsName(operation, true);
|
|
236
|
-
const parameters: Map<
|
|
237
|
-
string,
|
|
238
|
-
OptionalKind<ParameterDeclarationStructure>
|
|
239
|
-
> = new Map();
|
|
240
|
-
|
|
241
|
-
operation.parameters
|
|
242
|
-
.filter(
|
|
243
|
-
(p) =>
|
|
244
|
-
p.implementation === "Method" &&
|
|
245
|
-
p.type.type !== "constant" &&
|
|
246
|
-
p.clientDefaultValue === undefined &&
|
|
247
|
-
!p.optional
|
|
248
|
-
)
|
|
249
|
-
.map((p) => buildType(p.clientName, p.type, p.format))
|
|
250
|
-
.forEach((p) => {
|
|
251
|
-
parameters.set(p.name, p);
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
if (operation.bodyParameter) {
|
|
255
|
-
parameters.set(operation.bodyParameter?.clientName, {
|
|
256
|
-
hasQuestionToken: operation.bodyParameter.optional,
|
|
257
|
-
...buildType(
|
|
258
|
-
operation.bodyParameter.clientName,
|
|
259
|
-
operation.bodyParameter.type,
|
|
260
|
-
operation.bodyParameter.type.format
|
|
261
|
-
)
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
// Add context as the first parameter
|
|
265
|
-
const contextParam = { name: "context", type: clientType };
|
|
266
|
-
|
|
267
|
-
// Add the options parameter
|
|
268
|
-
const optionsParam = {
|
|
269
|
-
name: parameters.has("options") ? "optionalParams" : "options",
|
|
270
|
-
type: optionsType,
|
|
271
|
-
initializer: "{ requestOptions: {} }"
|
|
272
|
-
};
|
|
273
|
-
|
|
274
|
-
const finalParameters = [contextParam, ...parameters.values(), optionsParam];
|
|
275
|
-
|
|
276
|
-
return finalParameters;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* This operation builds and returns the function declaration for an operation.
|
|
281
|
-
*/
|
|
282
|
-
export function getOperationFunction(
|
|
283
|
-
operation: Operation,
|
|
284
|
-
clientType: string
|
|
285
|
-
): OptionalKind<FunctionDeclarationStructure> & { propertyName?: string } {
|
|
286
|
-
if (isPagingOnlyOperation(operation)) {
|
|
287
|
-
// Case 1: paging-only operation
|
|
288
|
-
return getPagingOnlyOperationFunction(operation, clientType);
|
|
289
|
-
} else if (isLroOnlyOperation(operation)) {
|
|
290
|
-
// Case 2: lro-only operation
|
|
291
|
-
return getLroOnlyOperationFunction(operation, clientType);
|
|
292
|
-
} else if (isLroAndPagingOperation(operation)) {
|
|
293
|
-
// Case 3: both paging + lro operation is not supported yet so handle them as normal operation and customization may be needed
|
|
294
|
-
// https://github.com/Azure/autorest.typescript/issues/2313
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Extract required parameters
|
|
298
|
-
const parameters: OptionalKind<ParameterDeclarationStructure>[] =
|
|
299
|
-
getOperationSignatureParameters(operation, clientType);
|
|
300
|
-
// TODO: Support operation overloads
|
|
301
|
-
const response = operation.responses[0]!;
|
|
302
|
-
let returnType = { name: "", type: "void" };
|
|
303
|
-
if (response.type?.type) {
|
|
304
|
-
const type =
|
|
305
|
-
extractPagingType(response.type, operation.itemName) ?? response.type;
|
|
306
|
-
returnType = buildType(type.name, type, type.format);
|
|
307
|
-
}
|
|
308
|
-
const { name, fixme = [] } = getOperationName(operation);
|
|
309
|
-
const functionStatement = {
|
|
310
|
-
docs: [
|
|
311
|
-
...getDocsFromDescription(operation.description),
|
|
312
|
-
...getFixmeForMultilineDocs(fixme)
|
|
313
|
-
],
|
|
314
|
-
isAsync: true,
|
|
315
|
-
isExported: true,
|
|
316
|
-
name,
|
|
317
|
-
propertyName: operation.name,
|
|
318
|
-
parameters,
|
|
319
|
-
returnType: `Promise<${returnType.type}>`
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
const statements: string[] = [];
|
|
323
|
-
statements.push(
|
|
324
|
-
`const result = await _${name}Send(${parameters
|
|
325
|
-
.map((p) => p.name)
|
|
326
|
-
.join(", ")});`
|
|
327
|
-
);
|
|
328
|
-
statements.push(`return _${name}Deserialize(result);`);
|
|
329
|
-
|
|
330
|
-
return {
|
|
331
|
-
...functionStatement,
|
|
332
|
-
statements
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
function getLroOnlyOperationFunction(operation: Operation, clientType: string) {
|
|
337
|
-
// Extract required parameters
|
|
338
|
-
const parameters: OptionalKind<ParameterDeclarationStructure>[] =
|
|
339
|
-
getOperationSignatureParameters(operation, clientType);
|
|
340
|
-
const returnType = buildLroReturnType(operation);
|
|
341
|
-
const { name, fixme = [] } = getOperationName(operation);
|
|
342
|
-
const functionStatement = {
|
|
343
|
-
docs: [
|
|
344
|
-
...getDocsFromDescription(operation.description),
|
|
345
|
-
...getFixmeForMultilineDocs(fixme)
|
|
346
|
-
],
|
|
347
|
-
isAsync: false,
|
|
348
|
-
isExported: true,
|
|
349
|
-
name,
|
|
350
|
-
propertyName: operation.name,
|
|
351
|
-
parameters,
|
|
352
|
-
returnType: `PollerLike<OperationState<${returnType.type}>, ${returnType.type}>`
|
|
353
|
-
};
|
|
354
|
-
|
|
355
|
-
const statements: string[] = [];
|
|
356
|
-
statements.push(`
|
|
357
|
-
return getLongRunningPoller(context, _${name}Deserialize, {
|
|
358
|
-
updateIntervalInMs: options?.updateIntervalInMs,
|
|
359
|
-
abortSignal: options?.abortSignal,
|
|
360
|
-
getInitialResponse: () => _${name}Send(${parameters
|
|
361
|
-
.map((p) => p.name)
|
|
362
|
-
.join(", ")})
|
|
363
|
-
}) as PollerLike<OperationState<${returnType.type}>, ${returnType.type}>;
|
|
364
|
-
`);
|
|
365
|
-
|
|
366
|
-
return {
|
|
367
|
-
...functionStatement,
|
|
368
|
-
statements
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
export function buildLroReturnType(operation: Operation) {
|
|
373
|
-
const metadata = operation.lroMetadata;
|
|
374
|
-
if (metadata !== undefined && metadata.finalResult !== undefined) {
|
|
375
|
-
const type = metadata.finalResult;
|
|
376
|
-
return buildType(type.name, type, type.format);
|
|
377
|
-
}
|
|
378
|
-
return { name: "", type: "void" };
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
export function getPagingOnlyOperationFunction(
|
|
382
|
-
operation: Operation,
|
|
383
|
-
clientType: string
|
|
384
|
-
) {
|
|
385
|
-
// Extract required parameters
|
|
386
|
-
const parameters: OptionalKind<ParameterDeclarationStructure>[] =
|
|
387
|
-
getOperationSignatureParameters(operation, clientType);
|
|
388
|
-
|
|
389
|
-
// TODO: Support operation overloads
|
|
390
|
-
const response = operation.responses[0];
|
|
391
|
-
let returnType = { name: "", type: "void" };
|
|
392
|
-
if (response?.type?.type) {
|
|
393
|
-
const type =
|
|
394
|
-
extractPagingType(response.type, operation.itemName) ?? response.type;
|
|
395
|
-
returnType = buildType(type.name, type, type.format);
|
|
396
|
-
}
|
|
397
|
-
const { name, fixme = [] } = getOperationName(operation);
|
|
398
|
-
const functionStatement = {
|
|
399
|
-
docs: [
|
|
400
|
-
...getDocsFromDescription(operation.description),
|
|
401
|
-
...getFixmeForMultilineDocs(fixme)
|
|
402
|
-
],
|
|
403
|
-
isAsync: false,
|
|
404
|
-
isExported: true,
|
|
405
|
-
name,
|
|
406
|
-
propertyName: operation.name,
|
|
407
|
-
parameters,
|
|
408
|
-
returnType: `PagedAsyncIterableIterator<${returnType.type}>`
|
|
409
|
-
};
|
|
410
|
-
|
|
411
|
-
const statements: string[] = [];
|
|
412
|
-
const options = [];
|
|
413
|
-
if (operation.itemName) {
|
|
414
|
-
options.push(`itemName: "${operation.itemName}"`);
|
|
415
|
-
}
|
|
416
|
-
if (operation.continuationTokenName) {
|
|
417
|
-
options.push(`nextLinkName: "${operation.continuationTokenName}"`);
|
|
418
|
-
}
|
|
419
|
-
statements.push(
|
|
420
|
-
`return buildPagedAsyncIterator(
|
|
421
|
-
context,
|
|
422
|
-
() => _${name}Send(${parameters.map((p) => p.name).join(", ")}),
|
|
423
|
-
_${name}Deserialize,
|
|
424
|
-
${options.length > 0 ? `{${options.join(", ")}}` : ``}
|
|
425
|
-
);`
|
|
426
|
-
);
|
|
427
|
-
|
|
428
|
-
return {
|
|
429
|
-
...functionStatement,
|
|
430
|
-
statements
|
|
431
|
-
};
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
function extractPagingType(type: Type, itemName?: string): Type | undefined {
|
|
435
|
-
if (!itemName) {
|
|
436
|
-
return undefined;
|
|
437
|
-
}
|
|
438
|
-
const prop = (type.properties ?? [])
|
|
439
|
-
?.filter((prop) => prop.restApiName === itemName)
|
|
440
|
-
.map((prop) => prop.type);
|
|
441
|
-
if (prop.length === 0) {
|
|
442
|
-
return undefined;
|
|
443
|
-
}
|
|
444
|
-
return prop[0]?.type === "list" && prop[0].elementType
|
|
445
|
-
? prop[0].elementType
|
|
446
|
-
: undefined;
|
|
447
|
-
}
|
|
448
|
-
export function getOperationOptionsName(
|
|
449
|
-
operation: Operation,
|
|
450
|
-
includeGroupName = false
|
|
451
|
-
) {
|
|
452
|
-
const prefix =
|
|
453
|
-
includeGroupName && operation.name.indexOf("_") === -1
|
|
454
|
-
? getClassicalLayerPrefix(operation, NameType.Interface)
|
|
455
|
-
: "";
|
|
456
|
-
const optionName = `${prefix}${toPascalCase(operation.name)}OptionalParams`;
|
|
457
|
-
return optionName;
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
/**
|
|
461
|
-
* This function build the request parameters that we will provide to the
|
|
462
|
-
* RLC internally. This will translate High Level parameters into the RLC ones.
|
|
463
|
-
* Figuring out what goes in headers, body, path and qsp.
|
|
464
|
-
*/
|
|
465
|
-
function getRequestParameters(
|
|
466
|
-
dpgContext: SdkContext,
|
|
467
|
-
operation: Operation,
|
|
468
|
-
serializerMap: SerializerMap,
|
|
469
|
-
runtimeImports: RuntimeImports
|
|
470
|
-
): string {
|
|
471
|
-
if (!operation.parameters) {
|
|
472
|
-
return "";
|
|
473
|
-
}
|
|
474
|
-
const operationParameters = operation.parameters.filter(
|
|
475
|
-
(p) => p.implementation !== "Client" && !isContentType(p)
|
|
476
|
-
);
|
|
477
|
-
|
|
478
|
-
const contentTypeParameter = operation.parameters.find(isContentType);
|
|
479
|
-
|
|
480
|
-
const parametersImplementation: Partial<
|
|
481
|
-
Record<ParameterLocation, Parameter[] | BodyParameter[]>
|
|
482
|
-
> = _.groupBy(operationParameters, (p) => p.location);
|
|
483
|
-
|
|
484
|
-
parametersImplementation["body"] = isDefined(operation.bodyParameter)
|
|
485
|
-
? [operation.bodyParameter]
|
|
486
|
-
: parametersImplementation["body"];
|
|
487
|
-
|
|
488
|
-
const params = [
|
|
489
|
-
...(contentTypeParameter
|
|
490
|
-
? [getContentTypeValue(contentTypeParameter)]
|
|
491
|
-
: []),
|
|
492
|
-
...[
|
|
493
|
-
(
|
|
494
|
-
[
|
|
495
|
-
["headers", "header"],
|
|
496
|
-
["queryParameters", "query"],
|
|
497
|
-
["body", "body"]
|
|
498
|
-
] as const
|
|
499
|
-
)
|
|
500
|
-
.map(
|
|
501
|
-
([id, location]) => [id, parametersImplementation[location]] as const
|
|
502
|
-
)
|
|
503
|
-
.filter(([_, paramList]) => paramList?.length)
|
|
504
|
-
.flatMap(([id, paramList]) =>
|
|
505
|
-
paramList!.map((i) => {
|
|
506
|
-
const initializer = serializeType({
|
|
507
|
-
dpgContext,
|
|
508
|
-
functionType: UsageFlags.Input,
|
|
509
|
-
serializerMap,
|
|
510
|
-
type: i.tcgcType!,
|
|
511
|
-
valueExpr:
|
|
512
|
-
id === "body" ? i.clientName : `options?.${i.clientName}`,
|
|
513
|
-
importCallback: (importType, importedName) =>
|
|
514
|
-
addImportToSpecifier(importType, runtimeImports, importedName)
|
|
515
|
-
});
|
|
516
|
-
return `${id}: ${initializer}`;
|
|
517
|
-
})
|
|
518
|
-
)
|
|
519
|
-
]
|
|
520
|
-
];
|
|
521
|
-
|
|
522
|
-
return params.join(",\n");
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
function isContentType(param: Parameter): boolean {
|
|
526
|
-
return (
|
|
527
|
-
param.location === "header" &&
|
|
528
|
-
param.restApiName.toLowerCase() === "content-type"
|
|
529
|
-
);
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
function getContentTypeValue(param: Parameter | Property) {
|
|
533
|
-
const defaultValue =
|
|
534
|
-
param.clientDefaultValue ?? param.type.clientDefaultValue;
|
|
535
|
-
|
|
536
|
-
if (defaultValue) {
|
|
537
|
-
return `contentType: options.${param.clientName} as any ?? "${defaultValue}"`;
|
|
538
|
-
} else {
|
|
539
|
-
return `contentType: ${
|
|
540
|
-
!param.optional
|
|
541
|
-
? "contentType"
|
|
542
|
-
: "options." + param.clientName + " as any"
|
|
543
|
-
}`;
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
/**
|
|
548
|
-
* Builds the assignment for when a property or parameter has a default value
|
|
549
|
-
*/
|
|
550
|
-
function getDefaultValue(param: Parameter | Property) {
|
|
551
|
-
return (param.clientDefaultValue ?? param.type.clientDefaultValue) !==
|
|
552
|
-
undefined
|
|
553
|
-
? `${param.optional ? "??" : ""} "${
|
|
554
|
-
param.clientDefaultValue ?? param.type.clientDefaultValue
|
|
555
|
-
}"`
|
|
556
|
-
: "";
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
/**
|
|
560
|
-
* Extracts the path parameters
|
|
561
|
-
*/
|
|
562
|
-
function getPathParameters(operation: Operation) {
|
|
563
|
-
if (!operation.parameters) {
|
|
564
|
-
return "";
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
let pathParams = "";
|
|
568
|
-
for (const param of operation.parameters) {
|
|
569
|
-
if (param.location === "path") {
|
|
570
|
-
if (!param.optional) {
|
|
571
|
-
pathParams += `${pathParams !== "" ? "," : ""} ${param.clientName}`;
|
|
572
|
-
continue;
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
const defaultValue = getDefaultValue(param);
|
|
576
|
-
|
|
577
|
-
pathParams += `${pathParams !== "" ? "," : ""} options.${
|
|
578
|
-
param.clientName
|
|
579
|
-
}`;
|
|
580
|
-
|
|
581
|
-
if (defaultValue) {
|
|
582
|
-
pathParams += ` ?? "${defaultValue}"`;
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
return pathParams;
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
/**
|
|
591
|
-
* This function helps converting strings into JS complex types recursively.
|
|
592
|
-
* We need to drill down into Array elements to make sure that the element type is
|
|
593
|
-
* deserialized correctly
|
|
594
|
-
*/
|
|
595
|
-
function deserializeResponseValue(
|
|
596
|
-
dpgContext: SdkContext,
|
|
597
|
-
serializerMap: SerializerMap,
|
|
598
|
-
type: Type,
|
|
599
|
-
restValue: string,
|
|
600
|
-
runtimeImports: RuntimeImports
|
|
601
|
-
): string {
|
|
602
|
-
return serializeType({
|
|
603
|
-
dpgContext,
|
|
604
|
-
functionType: UsageFlags.Output,
|
|
605
|
-
serializerMap,
|
|
606
|
-
type: type.tcgcType!,
|
|
607
|
-
valueExpr: restValue,
|
|
608
|
-
importCallback: (importType, importedName) =>
|
|
609
|
-
addImportToSpecifier(importType, runtimeImports, importedName)
|
|
610
|
-
});
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
function isLroAndPagingOperation(op: Operation): boolean {
|
|
614
|
-
return op.discriminator === "lropaging";
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
export function isLroOnlyOperation(op: Operation): boolean {
|
|
618
|
-
return op.discriminator === "lro";
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
export function hasPagingOnlyOperation(
|
|
622
|
-
client: Client,
|
|
623
|
-
needRLC?: boolean
|
|
624
|
-
): boolean;
|
|
625
|
-
export function hasPagingOnlyOperation(
|
|
626
|
-
codeModel: ModularCodeModel,
|
|
627
|
-
needRLC?: boolean
|
|
628
|
-
): boolean;
|
|
629
|
-
export function hasPagingOnlyOperation(
|
|
630
|
-
clientOrCodeModel: Client | ModularCodeModel,
|
|
631
|
-
needRLC: boolean = false
|
|
632
|
-
): boolean {
|
|
633
|
-
let clients: Client[] = [];
|
|
634
|
-
if ((clientOrCodeModel as any)?.operationGroups) {
|
|
635
|
-
clients = [clientOrCodeModel as Client];
|
|
636
|
-
} else if ((clientOrCodeModel as any)?.clients) {
|
|
637
|
-
clients = (clientOrCodeModel as ModularCodeModel).clients;
|
|
638
|
-
}
|
|
639
|
-
return clients.some(
|
|
640
|
-
(c) =>
|
|
641
|
-
(needRLC ? c.rlcHelperDetails.hasPaging : false) ||
|
|
642
|
-
(c.operationGroups ?? []).some((og) =>
|
|
643
|
-
(og.operations ?? []).some(isPagingOnlyOperation)
|
|
644
|
-
)
|
|
645
|
-
);
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
export function isPagingOnlyOperation(op: Operation): boolean {
|
|
649
|
-
return op.discriminator === "paging";
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
export function getAllAncestors(type: Type): Type[] {
|
|
653
|
-
const ancestors: Type[] = [];
|
|
654
|
-
type?.parents?.forEach((p) => {
|
|
655
|
-
ancestors.push(p);
|
|
656
|
-
ancestors.push(...getAllAncestors(p));
|
|
657
|
-
});
|
|
658
|
-
return ancestors;
|
|
659
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
SdkArrayType,
|
|
3
|
-
SdkType
|
|
4
|
-
} from "@azure-tools/typespec-client-generator-core";
|
|
5
|
-
import { UsageFlags } from "@typespec/compiler";
|
|
6
|
-
import { SerializeTypeOptions, serializeType } from "./serializers.js";
|
|
7
|
-
import { SerializerOutput, getModularTypeId, getRLCTypeId } from "./util.js";
|
|
8
|
-
|
|
9
|
-
export function serializeArray(
|
|
10
|
-
options: SerializeTypeOptions<SdkArrayType>
|
|
11
|
-
): SerializerOutput {
|
|
12
|
-
const { dpgContext, functionType, serializerMap, type, valueExpr } = options;
|
|
13
|
-
const valueType = type.valueType as SdkType & { name?: string };
|
|
14
|
-
const mapParameterId = "e";
|
|
15
|
-
|
|
16
|
-
const elementTypeName =
|
|
17
|
-
functionType === UsageFlags.Input
|
|
18
|
-
? getModularTypeId(valueType)
|
|
19
|
-
: getRLCTypeId(dpgContext, valueType);
|
|
20
|
-
|
|
21
|
-
const serializedChildExpr = serializeType({
|
|
22
|
-
...options,
|
|
23
|
-
type: valueType,
|
|
24
|
-
valueExpr: mapParameterId
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
if (serializedChildExpr === mapParameterId) {
|
|
28
|
-
// mapping over identity function, so map is unnecessary
|
|
29
|
-
// arr.map((e) => e) -> arr
|
|
30
|
-
return valueExpr;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// arr.map((e) => f(e)) -> arr.map(f)
|
|
34
|
-
const unaryFunctionInvocation =
|
|
35
|
-
/(?<functionName>\w+)\((?<childArgExpr>\w+)\)/;
|
|
36
|
-
|
|
37
|
-
const { functionName, childArgExpr } =
|
|
38
|
-
serializedChildExpr.match(unaryFunctionInvocation)?.groups ?? {};
|
|
39
|
-
|
|
40
|
-
const mapArg =
|
|
41
|
-
elementTypeName && serializerMap?.[elementTypeName]
|
|
42
|
-
? mapParameterId
|
|
43
|
-
: `${mapParameterId}: ${elementTypeName}`;
|
|
44
|
-
|
|
45
|
-
const mapFunction =
|
|
46
|
-
childArgExpr === mapParameterId
|
|
47
|
-
? functionName
|
|
48
|
-
: `(${mapArg})=>(${serializedChildExpr})`;
|
|
49
|
-
|
|
50
|
-
return `${valueExpr}.map(${mapFunction})`;
|
|
51
|
-
}
|