@azure-tools/typespec-ts 0.28.0 → 0.29.0-alpha.20240531.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 +12 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +24 -18
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib.d.ts +14 -4
- package/dist/src/lib.d.ts.map +1 -1
- package/dist/src/lib.js +9 -2
- package/dist/src/lib.js.map +1 -1
- package/dist/src/modular/buildClassicalClient.d.ts.map +1 -1
- package/dist/src/modular/buildClassicalClient.js +2 -0
- package/dist/src/modular/buildClassicalClient.js.map +1 -1
- package/dist/src/modular/buildClassicalOperationGroups.d.ts.map +1 -1
- package/dist/src/modular/buildClassicalOperationGroups.js +3 -0
- package/dist/src/modular/buildClassicalOperationGroups.js.map +1 -1
- package/dist/src/modular/buildCodeModel.d.ts.map +1 -1
- package/dist/src/modular/buildCodeModel.js +80 -83
- package/dist/src/modular/buildCodeModel.js.map +1 -1
- package/dist/src/modular/buildLroFiles.d.ts +24 -0
- package/dist/src/modular/buildLroFiles.d.ts.map +1 -0
- package/dist/src/modular/buildLroFiles.js +399 -0
- package/dist/src/modular/buildLroFiles.js.map +1 -0
- package/dist/src/modular/buildOperations.d.ts +6 -0
- package/dist/src/modular/buildOperations.d.ts.map +1 -1
- package/dist/src/modular/buildOperations.js +64 -5
- package/dist/src/modular/buildOperations.js.map +1 -1
- package/dist/src/modular/buildPagingFiles.js +3 -3
- package/dist/src/modular/buildPagingFiles.js.map +1 -1
- package/dist/src/modular/buildProjectFiles.d.ts +0 -3
- package/dist/src/modular/buildProjectFiles.d.ts.map +1 -1
- package/dist/src/modular/buildProjectFiles.js +0 -399
- package/dist/src/modular/buildProjectFiles.js.map +1 -1
- package/dist/src/modular/buildRootIndex.d.ts.map +1 -1
- package/dist/src/modular/buildRootIndex.js +20 -0
- package/dist/src/modular/buildRootIndex.js.map +1 -1
- package/dist/src/modular/buildSubpathIndex.js +4 -3
- package/dist/src/modular/buildSubpathIndex.js.map +1 -1
- package/dist/src/modular/emitModels.d.ts +2 -0
- package/dist/src/modular/emitModels.d.ts.map +1 -1
- package/dist/src/modular/emitModels.js +73 -11
- package/dist/src/modular/emitModels.js.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.d.ts +5 -5
- package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.js +171 -55
- 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/interfaces.d.ts +5 -0
- package/dist/src/modular/interfaces.d.ts.map +1 -1
- package/dist/src/modular/modularCodeModel.d.ts +9 -1
- package/dist/src/modular/modularCodeModel.d.ts.map +1 -1
- package/dist/src/transform/transformHelperFunctionDetails.js +1 -1
- package/dist/src/transform/transformParameters.js +2 -2
- package/dist/src/transform/transformParameters.js.map +1 -1
- package/dist/src/transform/transformPaths.js +1 -1
- package/dist/src/transform/transformPaths.js.map +1 -1
- package/dist/src/transform/transformResponses.js +2 -2
- 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 +23 -31
- package/dist/src/transform/transformSchemas.js.map +1 -1
- package/dist/src/transform/transfromRLCOptions.d.ts.map +1 -1
- package/dist/src/transform/transfromRLCOptions.js +8 -1
- package/dist/src/transform/transfromRLCOptions.js.map +1 -1
- package/dist/src/utils/modelUtils.d.ts +12 -2
- package/dist/src/utils/modelUtils.d.ts.map +1 -1
- package/dist/src/utils/modelUtils.js +88 -49
- package/dist/src/utils/modelUtils.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +19 -18
- package/src/index.ts +36 -22
- package/src/lib.ts +10 -2
- package/src/modular/buildClassicalClient.ts +2 -0
- package/src/modular/buildClassicalOperationGroups.ts +4 -0
- package/src/modular/buildCodeModel.ts +100 -155
- package/src/modular/buildLroFiles.ts +433 -0
- package/src/modular/buildOperations.ts +91 -10
- package/src/modular/buildPagingFiles.ts +4 -4
- package/src/modular/buildProjectFiles.ts +0 -471
- package/src/modular/buildRootIndex.ts +49 -0
- package/src/modular/buildSubpathIndex.ts +4 -4
- package/src/modular/emitModels.ts +102 -15
- package/src/modular/helpers/operationHelpers.ts +207 -72
- package/src/modular/helpers/typeHelpers.ts +6 -2
- package/src/modular/interfaces.ts +6 -0
- package/src/modular/modularCodeModel.ts +10 -1
- package/src/transform/transformHelperFunctionDetails.ts +1 -1
- package/src/transform/transformParameters.ts +2 -2
- package/src/transform/transformPaths.ts +1 -1
- package/src/transform/transformResponses.ts +2 -2
- package/src/transform/transformSchemas.ts +22 -33
- package/src/transform/transfromRLCOptions.ts +10 -1
- package/src/utils/modelUtils.ts +107 -46
|
@@ -19,24 +19,48 @@ function isAzureCoreErrorSdkType(t: Type) {
|
|
|
19
19
|
["error", "errormodel", "innererror", "errorresponse"].includes(
|
|
20
20
|
t.name.toLowerCase()
|
|
21
21
|
) &&
|
|
22
|
-
t.
|
|
22
|
+
t.coreTypeInfo === "ErrorType"
|
|
23
23
|
);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
function isAzureCoreLroSdkType(t: Type) {
|
|
27
|
+
return (
|
|
28
|
+
t.name &&
|
|
29
|
+
["operationstate"].includes(t.name.toLowerCase()) &&
|
|
30
|
+
t.coreTypeInfo === "LroType"
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function isAnonymousModel(t: Type) {
|
|
35
|
+
return t.type === "model" && t.name === "";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function isModelWithAdditionalProperties(t: Type) {
|
|
39
|
+
return t.type === "dict" && t.name !== "Record";
|
|
40
|
+
}
|
|
41
|
+
|
|
26
42
|
function getCoreClientErrorType(name: string, coreClientTypes: Set<string>) {
|
|
27
43
|
const coreClientType: string = name === "Error" ? "ErrorModel" : name;
|
|
28
44
|
coreClientTypes.add(coreClientType);
|
|
29
45
|
return coreClientType;
|
|
30
46
|
}
|
|
31
47
|
|
|
48
|
+
function getCoreLroType(name: string, coreLroTypes: Set<string>) {
|
|
49
|
+
const coreLroType = name === "OperationState" ? "CoreOperationStatus" : name;
|
|
50
|
+
coreLroTypes.add(coreLroType);
|
|
51
|
+
return coreLroType;
|
|
52
|
+
}
|
|
53
|
+
|
|
32
54
|
// ====== TYPE EXTRACTION ======
|
|
33
55
|
|
|
34
56
|
function extractModels(codeModel: ModularCodeModel): Type[] {
|
|
35
57
|
const models = codeModel.types.filter(
|
|
36
58
|
(t) =>
|
|
37
|
-
(t.type === "model" || t.type === "enum") &&
|
|
38
|
-
|
|
39
|
-
|
|
59
|
+
((t.type === "model" || t.type === "enum") &&
|
|
60
|
+
!isAzureCoreErrorSdkType(t) &&
|
|
61
|
+
!isAzureCoreLroSdkType(t) &&
|
|
62
|
+
!isAnonymousModel(t)) ||
|
|
63
|
+
isModelWithAdditionalProperties(t)
|
|
40
64
|
);
|
|
41
65
|
|
|
42
66
|
for (const model of codeModel.types) {
|
|
@@ -59,7 +83,10 @@ function extractModels(codeModel: ModularCodeModel): Type[] {
|
|
|
59
83
|
export function extractAliases(codeModel: ModularCodeModel): Type[] {
|
|
60
84
|
const models = codeModel.types.filter(
|
|
61
85
|
(t) =>
|
|
62
|
-
(t.type === "model" || t.type === "combined") &&
|
|
86
|
+
((t.type === "model" || t.type === "combined") &&
|
|
87
|
+
t.alias &&
|
|
88
|
+
t.aliasType) ||
|
|
89
|
+
(isModelWithAdditionalProperties(t) && t.alias && t.aliasType)
|
|
63
90
|
);
|
|
64
91
|
return models;
|
|
65
92
|
}
|
|
@@ -102,7 +129,7 @@ type InterfaceStructure = OptionalKind<InterfaceDeclarationStructure> & {
|
|
|
102
129
|
|
|
103
130
|
export function buildModelInterface(
|
|
104
131
|
model: Type,
|
|
105
|
-
cache: { coreClientTypes: Set<string> }
|
|
132
|
+
cache: { coreClientTypes: Set<string>; coreLroTypes: Set<string> }
|
|
106
133
|
): InterfaceStructure {
|
|
107
134
|
const modelProperties = model.properties ?? [];
|
|
108
135
|
const modelInterface = {
|
|
@@ -114,9 +141,13 @@ export function buildModelInterface(
|
|
|
114
141
|
const propertyMetadata = getType(p.type, p.format);
|
|
115
142
|
let propertyTypeName = propertyMetadata.name;
|
|
116
143
|
if (isAzureCoreErrorSdkType(p.type)) {
|
|
117
|
-
propertyTypeName =
|
|
118
|
-
|
|
119
|
-
|
|
144
|
+
propertyTypeName = getCoreClientErrorType(
|
|
145
|
+
propertyTypeName,
|
|
146
|
+
cache.coreClientTypes
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
if (isAzureCoreLroSdkType(p.type)) {
|
|
150
|
+
propertyTypeName = getCoreLroType(propertyTypeName, cache.coreLroTypes);
|
|
120
151
|
}
|
|
121
152
|
|
|
122
153
|
return {
|
|
@@ -142,6 +173,7 @@ export function buildModels(
|
|
|
142
173
|
): SourceFile | undefined {
|
|
143
174
|
// We are generating both models and enums here
|
|
144
175
|
const coreClientTypes = new Set<string>();
|
|
176
|
+
const coreLroTypes = new Set<string>();
|
|
145
177
|
// filter out the models/enums that are anonymous
|
|
146
178
|
const models = extractModels(codeModel).filter((m) => !!m.name);
|
|
147
179
|
const aliases = extractAliases(codeModel);
|
|
@@ -163,12 +195,21 @@ export function buildModels(
|
|
|
163
195
|
const enumAlias = buildEnumModel(model);
|
|
164
196
|
modelsFile.addTypeAlias(enumAlias);
|
|
165
197
|
} else {
|
|
166
|
-
const modelInterface = buildModelInterface(model, {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
198
|
+
const modelInterface = buildModelInterface(model, {
|
|
199
|
+
coreClientTypes,
|
|
200
|
+
coreLroTypes
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
model.parents?.forEach((p) =>
|
|
204
|
+
modelInterface.extends.push(p.alias ?? getType(p, p.format).name)
|
|
205
|
+
);
|
|
206
|
+
if (isModelWithAdditionalProperties(model)) {
|
|
207
|
+
addExtendedDictInfo(
|
|
208
|
+
model,
|
|
209
|
+
modelInterface,
|
|
210
|
+
codeModel.modularOptions.compatibilityMode
|
|
211
|
+
);
|
|
212
|
+
}
|
|
172
213
|
modelsFile.addInterface(modelInterface);
|
|
173
214
|
}
|
|
174
215
|
}
|
|
@@ -185,12 +226,58 @@ export function buildModels(
|
|
|
185
226
|
]);
|
|
186
227
|
}
|
|
187
228
|
|
|
229
|
+
if (coreLroTypes.size > 0) {
|
|
230
|
+
modelsFile.addImportDeclarations([
|
|
231
|
+
{
|
|
232
|
+
moduleSpecifier: getImportSpecifier(
|
|
233
|
+
"azureCoreLro",
|
|
234
|
+
codeModel.runtimeImports
|
|
235
|
+
),
|
|
236
|
+
namedImports: Array.from(coreLroTypes).map((t) =>
|
|
237
|
+
t === "CoreOperationStatus"
|
|
238
|
+
? "OperationStatus as CoreOperationStatus"
|
|
239
|
+
: t
|
|
240
|
+
)
|
|
241
|
+
}
|
|
242
|
+
]);
|
|
243
|
+
}
|
|
244
|
+
|
|
188
245
|
aliases.forEach((alias) => {
|
|
189
246
|
modelsFile.addTypeAlias(buildModelTypeAlias(alias));
|
|
190
247
|
});
|
|
191
248
|
return modelsFile;
|
|
192
249
|
}
|
|
193
250
|
|
|
251
|
+
function addExtendedDictInfo(
|
|
252
|
+
model: Type,
|
|
253
|
+
modelInterface: InterfaceStructure,
|
|
254
|
+
compatibilityMode: boolean = false
|
|
255
|
+
) {
|
|
256
|
+
if (
|
|
257
|
+
(model.properties &&
|
|
258
|
+
model.properties.length > 0 &&
|
|
259
|
+
model.elementType &&
|
|
260
|
+
model.properties?.every((p) => {
|
|
261
|
+
return getType(model.elementType!)?.name.includes(getType(p.type).name);
|
|
262
|
+
})) ||
|
|
263
|
+
(model.properties?.length === 0 && model.elementType)
|
|
264
|
+
) {
|
|
265
|
+
modelInterface.extends.push(
|
|
266
|
+
`Record<string, ${getType(model.elementType!).name ?? "any"}>`
|
|
267
|
+
);
|
|
268
|
+
} else if (compatibilityMode) {
|
|
269
|
+
modelInterface.extends.push(`Record<string, any>`);
|
|
270
|
+
} else {
|
|
271
|
+
modelInterface.properties?.push({
|
|
272
|
+
name: "additionalProperties",
|
|
273
|
+
docs: ["Additional properties"],
|
|
274
|
+
hasQuestionToken: true,
|
|
275
|
+
isReadonly: false,
|
|
276
|
+
type: `Record<string, ${getType(model.elementType!).name ?? "any"}>`
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
194
281
|
export function buildModelTypeAlias(model: Type) {
|
|
195
282
|
return {
|
|
196
283
|
name: model.name!,
|
|
@@ -59,6 +59,15 @@ function getRLCResponseType(rlcResponse?: OperationResponse) {
|
|
|
59
59
|
.join(" | ");
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
function getRLCLroLogicalResponse(rlcResponse?: OperationResponse) {
|
|
63
|
+
const logicalResponse = (rlcResponse?.responses ?? []).filter(
|
|
64
|
+
(r) => r.predefinedName && r.predefinedName.endsWith(`LogicalResponse`)
|
|
65
|
+
);
|
|
66
|
+
return logicalResponse.length > 0
|
|
67
|
+
? logicalResponse[0]!.predefinedName!
|
|
68
|
+
: "any";
|
|
69
|
+
}
|
|
70
|
+
|
|
62
71
|
export function getSendPrivateFunction(
|
|
63
72
|
dpgContext: SdkContext,
|
|
64
73
|
operation: Operation,
|
|
@@ -109,18 +118,22 @@ export function getDeserializePrivateFunction(
|
|
|
109
118
|
runtimeImports: RuntimeImports
|
|
110
119
|
): OptionalKind<FunctionDeclarationStructure> {
|
|
111
120
|
const { name } = getOperationName(operation);
|
|
112
|
-
|
|
113
121
|
const parameters: OptionalKind<ParameterDeclarationStructure>[] = [
|
|
114
122
|
{
|
|
115
123
|
name: "result",
|
|
116
124
|
type: getRLCResponseType(operation.rlcResponse)
|
|
117
125
|
}
|
|
118
126
|
];
|
|
127
|
+
// TODO: Support LRO + paging operation
|
|
128
|
+
// https://github.com/Azure/autorest.typescript/issues/2313
|
|
129
|
+
const isLroOnly = isLroOnlyOperation(operation);
|
|
119
130
|
|
|
120
131
|
// TODO: Support operation overloads
|
|
121
132
|
const response = operation.responses[0]!;
|
|
122
133
|
let returnType;
|
|
123
|
-
if (
|
|
134
|
+
if (isLroOnly && operation.method.toLowerCase() !== "patch") {
|
|
135
|
+
returnType = buildLroReturnType(operation);
|
|
136
|
+
} else if (response?.type?.type) {
|
|
124
137
|
returnType = buildType(
|
|
125
138
|
response.type.name,
|
|
126
139
|
response.type,
|
|
@@ -166,33 +179,69 @@ export function getDeserializePrivateFunction(
|
|
|
166
179
|
}
|
|
167
180
|
}
|
|
168
181
|
|
|
169
|
-
|
|
170
|
-
|
|
182
|
+
let deserializedType = isLroOnly
|
|
183
|
+
? operation?.lroMetadata?.finalResult
|
|
184
|
+
: response.type;
|
|
185
|
+
let hasLroSubPath = operation?.lroMetadata?.finalResultPath !== undefined;
|
|
186
|
+
let deserializedRoot = hasLroSubPath
|
|
187
|
+
? `result.body.${operation?.lroMetadata?.finalResultPath}`
|
|
188
|
+
: "result.body";
|
|
189
|
+
// TODO: Hard-coded for LRO PATCH case for now
|
|
190
|
+
// https://github.com/Azure/autorest.typescript/issues/2314
|
|
191
|
+
if (isLroOnly && operation.method.toLowerCase() === "patch") {
|
|
192
|
+
deserializedType = response.type;
|
|
193
|
+
hasLroSubPath = false;
|
|
194
|
+
deserializedRoot = "result.body";
|
|
195
|
+
}
|
|
196
|
+
if (isLroOnly) {
|
|
197
|
+
const lroLogicalResponse = getRLCLroLogicalResponse(operation.rlcResponse);
|
|
198
|
+
statements.push(`result = result as ${lroLogicalResponse};`);
|
|
199
|
+
if (hasLroSubPath) {
|
|
200
|
+
statements.push(
|
|
201
|
+
`if(${deserializedRoot.split(".").join("?.")} === undefined) {
|
|
202
|
+
throw createRestError(\`Expected a result in the response at position "${deserializedRoot}"\`, result);
|
|
203
|
+
}
|
|
204
|
+
`
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const allParents = deserializedType ? getAllAncestors(deserializedType) : [];
|
|
210
|
+
const properties = deserializedType
|
|
211
|
+
? getAllProperties(deserializedType, allParents)
|
|
212
|
+
: [];
|
|
171
213
|
if (
|
|
172
|
-
|
|
214
|
+
deserializedType?.type === "any" ||
|
|
215
|
+
deserializedType?.type === "dict" ||
|
|
216
|
+
(deserializedType?.type === "model" &&
|
|
217
|
+
allParents.some((p) => p.type === "dict")) ||
|
|
173
218
|
response.isBinaryPayload ||
|
|
174
|
-
|
|
219
|
+
deserializedType?.aliasType
|
|
175
220
|
) {
|
|
176
221
|
statements.push(`return result.body`);
|
|
177
|
-
} else if (properties.length > 0) {
|
|
222
|
+
} else if (deserializedType && properties.length > 0) {
|
|
178
223
|
statements.push(
|
|
179
224
|
`return {`,
|
|
180
|
-
getResponseMapping(
|
|
181
|
-
|
|
182
|
-
|
|
225
|
+
getResponseMapping(
|
|
226
|
+
deserializedType,
|
|
227
|
+
deserializedRoot,
|
|
228
|
+
runtimeImports
|
|
229
|
+
).join(","),
|
|
183
230
|
`}`
|
|
184
231
|
);
|
|
185
|
-
} else if (returnType.type === "void") {
|
|
232
|
+
} else if (returnType.type === "void" || deserializedType === undefined) {
|
|
186
233
|
statements.push(`return;`);
|
|
187
234
|
} else {
|
|
188
235
|
statements.push(
|
|
189
236
|
`return ${deserializeResponseValue(
|
|
190
|
-
|
|
191
|
-
|
|
237
|
+
deserializedType,
|
|
238
|
+
deserializedRoot,
|
|
192
239
|
runtimeImports,
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
240
|
+
deserializedType.nullable !== undefined
|
|
241
|
+
? !deserializedType.nullable
|
|
242
|
+
: false,
|
|
243
|
+
[deserializedType],
|
|
244
|
+
deserializedType.format
|
|
196
245
|
)}`
|
|
197
246
|
);
|
|
198
247
|
}
|
|
@@ -257,19 +306,115 @@ export function getOperationFunction(
|
|
|
257
306
|
operation: Operation,
|
|
258
307
|
clientType: string
|
|
259
308
|
): OptionalKind<FunctionDeclarationStructure> & { propertyName?: string } {
|
|
309
|
+
if (isPagingOnlyOperation(operation)) {
|
|
310
|
+
// Case 1: paging-only operation
|
|
311
|
+
return getPagingOnlyOperationFunction(operation, clientType);
|
|
312
|
+
} else if (isLroOnlyOperation(operation)) {
|
|
313
|
+
// Case 2: lro-only operation
|
|
314
|
+
return getLroOnlyOperationFunction(operation, clientType);
|
|
315
|
+
} else if (isLroAndPagingOperation(operation)) {
|
|
316
|
+
// Case 3: both paging + lro operation is not supported yet so handle them as normal operation and customization may be needed
|
|
317
|
+
// https://github.com/Azure/autorest.typescript/issues/2313
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Extract required parameters
|
|
321
|
+
const parameters: OptionalKind<ParameterDeclarationStructure>[] =
|
|
322
|
+
getOperationSignatureParameters(operation, clientType);
|
|
323
|
+
// TODO: Support operation overloads
|
|
324
|
+
const response = operation.responses[0]!;
|
|
325
|
+
let returnType = { name: "", type: "void" };
|
|
326
|
+
if (response.type?.type) {
|
|
327
|
+
const type =
|
|
328
|
+
extractPagingType(response.type, operation.itemName) ?? response.type;
|
|
329
|
+
returnType = buildType(type.name, type, type.format);
|
|
330
|
+
}
|
|
331
|
+
const { name, fixme = [] } = getOperationName(operation);
|
|
332
|
+
const functionStatement = {
|
|
333
|
+
docs: [
|
|
334
|
+
...getDocsFromDescription(operation.description),
|
|
335
|
+
...getFixmeForMultilineDocs(fixme)
|
|
336
|
+
],
|
|
337
|
+
isAsync: true,
|
|
338
|
+
isExported: true,
|
|
339
|
+
name,
|
|
340
|
+
propertyName: operation.name,
|
|
341
|
+
parameters,
|
|
342
|
+
returnType: `Promise<${returnType.type}>`
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
const statements: string[] = [];
|
|
346
|
+
statements.push(
|
|
347
|
+
`const result = await _${name}Send(${parameters
|
|
348
|
+
.map((p) => p.name)
|
|
349
|
+
.join(", ")});`
|
|
350
|
+
);
|
|
351
|
+
statements.push(`return _${name}Deserialize(result);`);
|
|
352
|
+
|
|
353
|
+
return {
|
|
354
|
+
...functionStatement,
|
|
355
|
+
statements
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
function getLroOnlyOperationFunction(operation: Operation, clientType: string) {
|
|
360
|
+
// Extract required parameters
|
|
361
|
+
const parameters: OptionalKind<ParameterDeclarationStructure>[] =
|
|
362
|
+
getOperationSignatureParameters(operation, clientType);
|
|
363
|
+
const returnType = buildLroReturnType(operation);
|
|
364
|
+
const { name, fixme = [] } = getOperationName(operation);
|
|
365
|
+
const functionStatement = {
|
|
366
|
+
docs: [
|
|
367
|
+
...getDocsFromDescription(operation.description),
|
|
368
|
+
...getFixmeForMultilineDocs(fixme)
|
|
369
|
+
],
|
|
370
|
+
isAsync: false,
|
|
371
|
+
isExported: true,
|
|
372
|
+
name,
|
|
373
|
+
propertyName: operation.name,
|
|
374
|
+
parameters,
|
|
375
|
+
returnType: `PollerLike<OperationState<${returnType.type}>, ${returnType.type}>`
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
const statements: string[] = [];
|
|
379
|
+
statements.push(`
|
|
380
|
+
return getLongRunningPoller(context, _${name}Deserialize, {
|
|
381
|
+
updateIntervalInMs: options?.updateIntervalInMs,
|
|
382
|
+
abortSignal: options?.abortSignal,
|
|
383
|
+
getInitialResponse: () => _${name}Send(${parameters
|
|
384
|
+
.map((p) => p.name)
|
|
385
|
+
.join(", ")})
|
|
386
|
+
}) as PollerLike<OperationState<${returnType.type}>, ${returnType.type}>;
|
|
387
|
+
`);
|
|
388
|
+
|
|
389
|
+
return {
|
|
390
|
+
...functionStatement,
|
|
391
|
+
statements
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
function buildLroReturnType(operation: Operation) {
|
|
396
|
+
const metadata = operation.lroMetadata;
|
|
397
|
+
if (metadata !== undefined && metadata.finalResult !== undefined) {
|
|
398
|
+
const type = metadata.finalResult;
|
|
399
|
+
return buildType(type.name, type, type.format);
|
|
400
|
+
}
|
|
401
|
+
return { name: "", type: "void" };
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
function getPagingOnlyOperationFunction(
|
|
405
|
+
operation: Operation,
|
|
406
|
+
clientType: string
|
|
407
|
+
) {
|
|
260
408
|
// Extract required parameters
|
|
261
409
|
const parameters: OptionalKind<ParameterDeclarationStructure>[] =
|
|
262
410
|
getOperationSignatureParameters(operation, clientType);
|
|
263
|
-
const isPaging = isPagingOperation(operation);
|
|
264
411
|
|
|
265
412
|
// TODO: Support operation overloads
|
|
266
413
|
const response = operation.responses[0]!;
|
|
267
414
|
let returnType = { name: "", type: "void" };
|
|
268
415
|
if (response.type?.type) {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
type = extractPagingType(type, operation.itemName) ?? type;
|
|
272
|
-
}
|
|
416
|
+
const type =
|
|
417
|
+
extractPagingType(response.type, operation.itemName) ?? response.type;
|
|
273
418
|
returnType = buildType(type.name, type, type.format);
|
|
274
419
|
}
|
|
275
420
|
const { name, fixme = [] } = getOperationName(operation);
|
|
@@ -278,41 +423,30 @@ export function getOperationFunction(
|
|
|
278
423
|
...getDocsFromDescription(operation.description),
|
|
279
424
|
...getFixmeForMultilineDocs(fixme)
|
|
280
425
|
],
|
|
281
|
-
isAsync:
|
|
426
|
+
isAsync: false,
|
|
282
427
|
isExported: true,
|
|
283
428
|
name,
|
|
284
429
|
propertyName: operation.name,
|
|
285
430
|
parameters,
|
|
286
|
-
returnType:
|
|
287
|
-
? `PagedAsyncIterableIterator<${returnType.type}>`
|
|
288
|
-
: `Promise<${returnType.type}>`
|
|
431
|
+
returnType: `PagedAsyncIterableIterator<${returnType.type}>`
|
|
289
432
|
};
|
|
290
433
|
|
|
291
434
|
const statements: string[] = [];
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
options.push(`nextLinkName: "${operation.continuationTokenName}"`);
|
|
299
|
-
}
|
|
300
|
-
statements.push(
|
|
301
|
-
`return buildPagedAsyncIterator(
|
|
302
|
-
context,
|
|
303
|
-
() => _${name}Send(${parameters.map((p) => p.name).join(", ")}),
|
|
304
|
-
_${name}Deserialize,
|
|
305
|
-
${options.length > 0 ? `{${options.join(", ")}}` : ``}
|
|
306
|
-
);`
|
|
307
|
-
);
|
|
308
|
-
} else {
|
|
309
|
-
statements.push(
|
|
310
|
-
`const result = await _${name}Send(${parameters
|
|
311
|
-
.map((p) => p.name)
|
|
312
|
-
.join(", ")});`
|
|
313
|
-
);
|
|
314
|
-
statements.push(`return _${name}Deserialize(result);`);
|
|
435
|
+
const options = [];
|
|
436
|
+
if (operation.itemName) {
|
|
437
|
+
options.push(`itemName: "${operation.itemName}"`);
|
|
438
|
+
}
|
|
439
|
+
if (operation.continuationTokenName) {
|
|
440
|
+
options.push(`nextLinkName: "${operation.continuationTokenName}"`);
|
|
315
441
|
}
|
|
442
|
+
statements.push(
|
|
443
|
+
`return buildPagedAsyncIterator(
|
|
444
|
+
context,
|
|
445
|
+
() => _${name}Send(${parameters.map((p) => p.name).join(", ")}),
|
|
446
|
+
_${name}Deserialize,
|
|
447
|
+
${options.length > 0 ? `{${options.join(", ")}}` : ``}
|
|
448
|
+
);`
|
|
449
|
+
);
|
|
316
450
|
|
|
317
451
|
return {
|
|
318
452
|
...functionStatement,
|
|
@@ -453,7 +587,12 @@ function buildBodyParameter(
|
|
|
453
587
|
return "";
|
|
454
588
|
}
|
|
455
589
|
|
|
456
|
-
|
|
590
|
+
const allParents = getAllAncestors(bodyParameter.type);
|
|
591
|
+
if (
|
|
592
|
+
bodyParameter.type.type === "model" &&
|
|
593
|
+
!bodyParameter.type.aliasType &&
|
|
594
|
+
!allParents.some((p) => p.type === "dict")
|
|
595
|
+
) {
|
|
457
596
|
const bodyParts: string[] = getRequestModelMapping(
|
|
458
597
|
bodyParameter.type,
|
|
459
598
|
bodyParameter.clientName,
|
|
@@ -470,8 +609,10 @@ function buildBodyParameter(
|
|
|
470
609
|
return `\nbody: ${bodyParameter.clientName},`;
|
|
471
610
|
}
|
|
472
611
|
} else if (
|
|
473
|
-
bodyParameter.type.type === "model" &&
|
|
474
|
-
|
|
612
|
+
(bodyParameter.type.type === "model" &&
|
|
613
|
+
(bodyParameter.type.aliasType ||
|
|
614
|
+
allParents.some((p) => p.type === "dict"))) ||
|
|
615
|
+
bodyParameter.type.type === "dict"
|
|
475
616
|
) {
|
|
476
617
|
return `\nbody: ${bodyParameter.clientName},`;
|
|
477
618
|
}
|
|
@@ -790,7 +931,7 @@ export function getRequestModelMapping(
|
|
|
790
931
|
const propertyFullName = `${propertyPath}.${property.clientName}`;
|
|
791
932
|
if (property.type.type === "model") {
|
|
792
933
|
let definition;
|
|
793
|
-
if (property.type.
|
|
934
|
+
if (property.type.coreTypeInfo === "ErrorType") {
|
|
794
935
|
definition = `"${property.restApiName}": ${getNullableCheck(
|
|
795
936
|
propertyFullName,
|
|
796
937
|
property.type
|
|
@@ -885,7 +1026,7 @@ export function getResponseMapping(
|
|
|
885
1026
|
const propertyFullName = `${propertyPath}.${property.restApiName}`;
|
|
886
1027
|
if (property.type.type === "model") {
|
|
887
1028
|
let definition;
|
|
888
|
-
if (property.type.
|
|
1029
|
+
if (property.type.coreTypeInfo === "ErrorType") {
|
|
889
1030
|
definition = `"${property.clientName}": ${getNullableCheck(
|
|
890
1031
|
propertyFullName,
|
|
891
1032
|
property.type
|
|
@@ -1173,29 +1314,23 @@ function needsDeserialize(type?: Type) {
|
|
|
1173
1314
|
);
|
|
1174
1315
|
}
|
|
1175
1316
|
|
|
1176
|
-
export function
|
|
1177
|
-
|
|
1178
|
-
needRLC: boolean = false
|
|
1179
|
-
) {
|
|
1180
|
-
return (codeModel.clients ?? []).some(
|
|
1181
|
-
(c) =>
|
|
1182
|
-
(needRLC ? c.rlcHelperDetails.hasLongRunning : false) ||
|
|
1183
|
-
(c.operationGroups ?? []).some((og) =>
|
|
1184
|
-
(og.operations ?? []).some(isLROOperation)
|
|
1185
|
-
)
|
|
1186
|
-
);
|
|
1317
|
+
export function isLroAndPagingOperation(op: Operation): boolean {
|
|
1318
|
+
return op.discriminator === "lropaging";
|
|
1187
1319
|
}
|
|
1188
1320
|
|
|
1189
|
-
export function
|
|
1190
|
-
return op.discriminator === "lro"
|
|
1321
|
+
export function isLroOnlyOperation(op: Operation): boolean {
|
|
1322
|
+
return op.discriminator === "lro";
|
|
1191
1323
|
}
|
|
1192
1324
|
|
|
1193
|
-
export function
|
|
1194
|
-
|
|
1325
|
+
export function hasPagingOnlyOperation(
|
|
1326
|
+
client: Client,
|
|
1327
|
+
needRLC?: boolean
|
|
1328
|
+
): boolean;
|
|
1329
|
+
export function hasPagingOnlyOperation(
|
|
1195
1330
|
codeModel: ModularCodeModel,
|
|
1196
1331
|
needRLC?: boolean
|
|
1197
1332
|
): boolean;
|
|
1198
|
-
export function
|
|
1333
|
+
export function hasPagingOnlyOperation(
|
|
1199
1334
|
clientOrCodeModel: Client | ModularCodeModel,
|
|
1200
1335
|
needRLC: boolean = false
|
|
1201
1336
|
): boolean {
|
|
@@ -1209,13 +1344,13 @@ export function hasPagingOperation(
|
|
|
1209
1344
|
(c) =>
|
|
1210
1345
|
(needRLC ? c.rlcHelperDetails.hasPaging : false) ||
|
|
1211
1346
|
(c.operationGroups ?? []).some((og) =>
|
|
1212
|
-
(og.operations ?? []).some(
|
|
1347
|
+
(og.operations ?? []).some(isPagingOnlyOperation)
|
|
1213
1348
|
)
|
|
1214
1349
|
);
|
|
1215
1350
|
}
|
|
1216
1351
|
|
|
1217
|
-
export function
|
|
1218
|
-
return op.discriminator === "paging"
|
|
1352
|
+
export function isPagingOnlyOperation(op: Operation): boolean {
|
|
1353
|
+
return op.discriminator === "paging";
|
|
1219
1354
|
}
|
|
1220
1355
|
|
|
1221
1356
|
export function getAllProperties(type: Type, parents?: Type[]): Property[] {
|
|
@@ -30,7 +30,7 @@ const simpleTypeMap: Record<string, TypeMetadata> = {
|
|
|
30
30
|
"byte-array": { name: "Uint8Array" },
|
|
31
31
|
string: { name: "string" },
|
|
32
32
|
any: { name: "Record<string, any>" },
|
|
33
|
-
unknown: { name: "
|
|
33
|
+
unknown: { name: "any" }
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
function handleAnomymousModelName(type: Type) {
|
|
@@ -232,7 +232,11 @@ function handleDictType(type: Type): TypeMetadata {
|
|
|
232
232
|
if (!type.elementType) {
|
|
233
233
|
throw new Error("Unable to process dict without elemetType info");
|
|
234
234
|
}
|
|
235
|
-
|
|
235
|
+
if (type.name && type.name !== "Record") {
|
|
236
|
+
return {
|
|
237
|
+
name: type.name
|
|
238
|
+
};
|
|
239
|
+
}
|
|
236
240
|
const elementType = getType(type.elementType, type.elementType.format);
|
|
237
241
|
const elementName = elementType.name;
|
|
238
242
|
return {
|
|
@@ -6,6 +6,7 @@ import { Project } from "ts-morph";
|
|
|
6
6
|
|
|
7
7
|
export interface ModularOptions {
|
|
8
8
|
sourceRoot: string;
|
|
9
|
+
compatibilityMode: boolean;
|
|
9
10
|
}
|
|
10
11
|
export interface ModularCodeModel {
|
|
11
12
|
options: RLCOptions;
|
|
@@ -101,7 +102,7 @@ export interface Type {
|
|
|
101
102
|
format?: string;
|
|
102
103
|
properties?: Property[];
|
|
103
104
|
types?: Type[];
|
|
104
|
-
|
|
105
|
+
coreTypeInfo?: "ErrorType" | "LroType";
|
|
105
106
|
usage?: UsageFlags;
|
|
106
107
|
alias?: string;
|
|
107
108
|
aliasType?: string;
|
|
@@ -182,4 +183,12 @@ export interface Operation {
|
|
|
182
183
|
addedOn?: string;
|
|
183
184
|
rlcResponse?: OperationResponse;
|
|
184
185
|
namespaceHierarchies: string[];
|
|
186
|
+
lroMetadata?: LroOperationMetadata;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export interface LroOperationMetadata {
|
|
190
|
+
finalStateVia?: string;
|
|
191
|
+
finalResult?: Type;
|
|
192
|
+
/** The path to the field in the 'finalEnvelopeResult' that contains the 'finalResult'. */
|
|
193
|
+
finalResultPath?: string;
|
|
185
194
|
}
|
|
@@ -23,7 +23,7 @@ export function transformHelperFunctionDetails(
|
|
|
23
23
|
): HelperFunctionDetails {
|
|
24
24
|
const program = dpgContext.program;
|
|
25
25
|
const serializeInfo = extractSpecialSerializeInfo(client, dpgContext);
|
|
26
|
-
//
|
|
26
|
+
// Disable paging and long running for non-Azure clients.
|
|
27
27
|
if (flavor !== "azure") {
|
|
28
28
|
return {
|
|
29
29
|
hasLongRunning: false,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
SchemaContext,
|
|
12
12
|
ApiVersionInfo
|
|
13
13
|
} from "@azure-tools/rlc-common";
|
|
14
|
-
import { ignoreDiagnostics, Type } from "@typespec/compiler";
|
|
14
|
+
import { ignoreDiagnostics, isVoidType, Type } from "@typespec/compiler";
|
|
15
15
|
import {
|
|
16
16
|
getHttpOperation,
|
|
17
17
|
HttpOperation,
|
|
@@ -259,7 +259,7 @@ function transformBodyParameters(
|
|
|
259
259
|
(parameters.bodyType ?? parameters.bodyParameter?.type) && inputBodyType
|
|
260
260
|
? inputBodyType
|
|
261
261
|
: parameters.bodyType ?? parameters.bodyParameter?.type;
|
|
262
|
-
if (!bodyType) {
|
|
262
|
+
if (!bodyType || isVoidType(bodyType)) {
|
|
263
263
|
return;
|
|
264
264
|
}
|
|
265
265
|
return transformRequestBody(
|