@azure-tools/typespec-ts 0.48.1 → 0.49.0-alpha.20260203.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 +11 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/modular/buildClientContext.d.ts.map +1 -1
- package/dist/src/modular/buildClientContext.js +6 -25
- package/dist/src/modular/buildClientContext.js.map +1 -1
- package/dist/src/modular/buildOperations.d.ts.map +1 -1
- package/dist/src/modular/buildOperations.js +1 -1
- package/dist/src/modular/buildOperations.js.map +1 -1
- package/dist/src/modular/buildProjectFiles.d.ts.map +1 -1
- package/dist/src/modular/buildProjectFiles.js +13 -10
- package/dist/src/modular/buildProjectFiles.js.map +1 -1
- package/dist/src/modular/buildRestorePoller.d.ts.map +1 -1
- package/dist/src/modular/buildRestorePoller.js +9 -2
- package/dist/src/modular/buildRestorePoller.js.map +1 -1
- package/dist/src/modular/emitModels.d.ts.map +1 -1
- package/dist/src/modular/emitModels.js +18 -4
- package/dist/src/modular/emitModels.js.map +1 -1
- package/dist/src/modular/emitSamples.d.ts.map +1 -1
- package/dist/src/modular/emitSamples.js +19 -1
- package/dist/src/modular/emitSamples.js.map +1 -1
- package/dist/src/modular/helpers/clientHelpers.d.ts +1 -0
- package/dist/src/modular/helpers/clientHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/clientHelpers.js +28 -8
- package/dist/src/modular/helpers/clientHelpers.js.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.d.ts +2 -2
- package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.js +53 -9
- package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
- package/dist/src/modular/helpers/typeHelpers.js +1 -1
- package/dist/src/modular/helpers/typeHelpers.js.map +1 -1
- package/dist/src/modular/serialization/buildDeserializerFunction.js +5 -1
- package/dist/src/modular/serialization/buildDeserializerFunction.js.map +1 -1
- package/dist/src/modular/serialization/buildSerializerFunction.js +5 -1
- package/dist/src/modular/serialization/buildSerializerFunction.js.map +1 -1
- package/dist/src/modular/serialization/serializeUtils.d.ts.map +1 -1
- package/dist/src/modular/serialization/serializeUtils.js +1 -0
- package/dist/src/modular/serialization/serializeUtils.js.map +1 -1
- package/dist/src/modular/type-expressions/get-type-expression.js +1 -1
- package/dist/src/modular/type-expressions/get-type-expression.js.map +1 -1
- package/dist/src/transform/transform.d.ts.map +1 -1
- package/dist/src/transform/transform.js +10 -10
- package/dist/src/transform/transform.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/transformSchemas.d.ts.map +1 -1
- package/dist/src/transform/transformSchemas.js +4 -4
- package/dist/src/transform/transformSchemas.js.map +1 -1
- package/dist/src/transform/transfromRLCOptions.d.ts +1 -1
- package/dist/src/transform/transfromRLCOptions.d.ts.map +1 -1
- package/dist/src/transform/transfromRLCOptions.js +25 -24
- package/dist/src/transform/transfromRLCOptions.js.map +1 -1
- package/dist/src/utils/clientUtils.d.ts +1 -1
- package/dist/src/utils/clientUtils.d.ts.map +1 -1
- package/dist/src/utils/clientUtils.js +47 -15
- package/dist/src/utils/clientUtils.js.map +1 -1
- package/dist/src/utils/crossLanguageDef.d.ts.map +1 -1
- package/dist/src/utils/crossLanguageDef.js +9 -3
- package/dist/src/utils/crossLanguageDef.js.map +1 -1
- package/dist/src/utils/interfaces.d.ts +2 -1
- package/dist/src/utils/interfaces.d.ts.map +1 -1
- package/dist/src/utils/modelUtils.d.ts +1 -1
- package/dist/src/utils/modelUtils.d.ts.map +1 -1
- package/dist/src/utils/modelUtils.js +14 -9
- package/dist/src/utils/modelUtils.js.map +1 -1
- package/dist/src/utils/operationUtil.d.ts +1 -1
- package/dist/src/utils/operationUtil.d.ts.map +1 -1
- package/dist/src/utils/operationUtil.js +7 -4
- package/dist/src/utils/operationUtil.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/src/index.ts +2 -0
- package/src/modular/buildClientContext.ts +6 -26
- package/src/modular/buildOperations.ts +0 -1
- package/src/modular/buildProjectFiles.ts +19 -16
- package/src/modular/buildRestorePoller.ts +9 -2
- package/src/modular/emitModels.ts +16 -3
- package/src/modular/emitSamples.ts +29 -1
- package/src/modular/helpers/clientHelpers.ts +33 -11
- package/src/modular/helpers/operationHelpers.ts +60 -16
- package/src/modular/helpers/typeHelpers.ts +1 -1
- package/src/modular/serialization/buildDeserializerFunction.ts +5 -1
- package/src/modular/serialization/buildSerializerFunction.ts +5 -1
- package/src/modular/serialization/serializeUtils.ts +1 -0
- package/src/modular/type-expressions/get-type-expression.ts +1 -1
- package/src/transform/transform.ts +5 -2
- package/src/transform/transformPaths.ts +1 -1
- package/src/transform/transformSchemas.ts +4 -1
- package/src/transform/transfromRLCOptions.ts +45 -24
- package/src/utils/clientUtils.ts +55 -14
- package/src/utils/crossLanguageDef.ts +8 -0
- package/src/utils/interfaces.ts +2 -1
- package/src/utils/modelUtils.ts +20 -6
- package/src/utils/operationUtil.ts +11 -3
- package/static/static-helpers/pagingHelpers.ts +32 -6
- package/static/static-helpers/pollingHelpers.ts +27 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@azure-tools/typespec-ts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.49.0-alpha.20260203.1",
|
|
4
4
|
"description": "An experimental TypeSpec emitter for TypeScript RLC",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -18,15 +18,15 @@
|
|
|
18
18
|
"license": "MIT",
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"@azure-rest/core-client": "^2.3.1",
|
|
21
|
-
"@typespec/http-specs": "0.1.0-alpha.
|
|
22
|
-
"@typespec/spector": "0.1.0-alpha.23-dev.
|
|
21
|
+
"@typespec/http-specs": "0.1.0-alpha.32-dev.1",
|
|
22
|
+
"@typespec/spector": "0.1.0-alpha.23-dev.1",
|
|
23
23
|
"@typespec/spec-api": "0.1.0-alpha.13-dev.0",
|
|
24
24
|
"@typespec/tspd": "0.73.3",
|
|
25
|
-
"@azure-tools/azure-http-specs": "0.1.0-alpha.37-dev.
|
|
25
|
+
"@azure-tools/azure-http-specs": "0.1.0-alpha.37-dev.1",
|
|
26
26
|
"@azure-tools/typespec-autorest": "^0.64.0",
|
|
27
27
|
"@azure-tools/typespec-azure-core": "^0.64.0",
|
|
28
28
|
"@azure-tools/typespec-azure-resource-manager": "^0.64.0",
|
|
29
|
-
"@azure-tools/typespec-client-generator-core": "^0.64.
|
|
29
|
+
"@azure-tools/typespec-client-generator-core": "^0.64.4",
|
|
30
30
|
"@azure/abort-controller": "^2.1.2",
|
|
31
31
|
"@azure/core-auth": "^1.6.0",
|
|
32
32
|
"@azure/core-lro": "^3.1.0",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
67
|
"@azure-tools/typespec-azure-core": "^0.64.0",
|
|
68
|
-
"@azure-tools/typespec-client-generator-core": "^0.64.
|
|
68
|
+
"@azure-tools/typespec-client-generator-core": "^0.64.4",
|
|
69
69
|
"@typespec/compiler": "^1.8.0",
|
|
70
70
|
"@typespec/http": "^1.8.0",
|
|
71
71
|
"@typespec/rest": "^0.78.0",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"@typespec/xml": "^0.78.0"
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
|
-
"@azure-tools/rlc-common": "
|
|
76
|
+
"@azure-tools/rlc-common": "0.49.0-alpha.20260203.1",
|
|
77
77
|
"fast-xml-parser": "^4.5.0",
|
|
78
78
|
"fs-extra": "^11.1.0",
|
|
79
79
|
"lodash": "^4.17.21",
|
package/src/index.ts
CHANGED
|
@@ -82,6 +82,7 @@ import { buildRestorePoller } from "./modular/buildRestorePoller.js";
|
|
|
82
82
|
import { buildSubpathIndexFile } from "./modular/buildSubpathIndex.js";
|
|
83
83
|
import {
|
|
84
84
|
createSdkContext,
|
|
85
|
+
listAllServiceNamespaces,
|
|
85
86
|
SdkClientType,
|
|
86
87
|
SdkServiceOperation
|
|
87
88
|
} from "@azure-tools/typespec-client-generator-core";
|
|
@@ -192,6 +193,7 @@ export async function $onEmit(context: EmitContext) {
|
|
|
192
193
|
const generationPathDetail: GenerationDirDetail =
|
|
193
194
|
await calculateGenerationDir();
|
|
194
195
|
dpgContext.generationPathDetail = generationPathDetail;
|
|
196
|
+
dpgContext.allServiceNamespaces = listAllServiceNamespaces(dpgContext);
|
|
195
197
|
const options: RLCOptions = transformRLCOptions(emitterOptions, dpgContext);
|
|
196
198
|
emitterOptions["is-modular-library"] = options.isModularLibrary;
|
|
197
199
|
emitterOptions["generate-sample"] = options.generateSample;
|
|
@@ -81,8 +81,7 @@ export function buildClientContext(
|
|
|
81
81
|
// Get all client parameters (both required and optional) for the interface
|
|
82
82
|
const requiredInterfaceProperties = getClientParameters(client, dpgContext, {
|
|
83
83
|
onClientOnly: false,
|
|
84
|
-
requiredOnly: true
|
|
85
|
-
apiVersionAsRequired: true
|
|
84
|
+
requiredOnly: true
|
|
86
85
|
})
|
|
87
86
|
.filter((p) => {
|
|
88
87
|
const clientParamName = getClientParameterName(p);
|
|
@@ -239,7 +238,7 @@ export function buildClientContext(
|
|
|
239
238
|
`);
|
|
240
239
|
}
|
|
241
240
|
|
|
242
|
-
let
|
|
241
|
+
let apiVersionStatement = ``;
|
|
243
242
|
const endpointParameter = getClientParameters(client, dpgContext, {
|
|
244
243
|
onClientOnly: false,
|
|
245
244
|
requiredOnly: true,
|
|
@@ -255,39 +254,20 @@ export function buildClientContext(
|
|
|
255
254
|
const apiVersionInEndpoint =
|
|
256
255
|
templateArguments && templateArguments.find((p) => p.isApiVersionParam);
|
|
257
256
|
if (!apiVersionInEndpoint && apiVersionParam.clientDefaultValue) {
|
|
258
|
-
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
if (apiVersionParam.kind === "method") {
|
|
262
|
-
apiVersionPolicyStatement += `
|
|
263
|
-
clientContext.pipeline.addPolicy({
|
|
264
|
-
name: 'ClientApiVersionPolicy',
|
|
265
|
-
sendRequest: (req, next) => {
|
|
266
|
-
// Use the apiVersion defined in request url directly
|
|
267
|
-
// Append one if there is no apiVersion and we have one at client options
|
|
268
|
-
const url = new URL(req.url);
|
|
269
|
-
if (!url.searchParams.get("api-version")) {
|
|
270
|
-
req.url = \`\${req.url}\${
|
|
271
|
-
Array.from(url.searchParams.keys()).length > 0 ? "&" : "?"
|
|
272
|
-
}api-version=\${${getClientParameterName(apiVersionParam)}}\`;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
return next(req);
|
|
276
|
-
},
|
|
277
|
-
});`;
|
|
257
|
+
apiVersionStatement += `const ${apiVersionParamName} = options.${apiVersionParamName};`;
|
|
278
258
|
}
|
|
279
259
|
} else if (isAzurePackage(emitterOptions)) {
|
|
280
|
-
|
|
260
|
+
apiVersionStatement += `
|
|
281
261
|
if (options.apiVersion) {
|
|
282
262
|
logger.warning("This client does not support client api-version, please change it at the operation level");
|
|
283
263
|
}`;
|
|
284
264
|
} else {
|
|
285
|
-
|
|
265
|
+
apiVersionStatement += `
|
|
286
266
|
if (options.apiVersion) {
|
|
287
267
|
console.warn("This client does not support client api-version, please change it at the operation level");
|
|
288
268
|
}`;
|
|
289
269
|
}
|
|
290
|
-
factoryFunction.addStatements(
|
|
270
|
+
factoryFunction.addStatements(apiVersionStatement);
|
|
291
271
|
|
|
292
272
|
const contextRequiredParam = requiredParams.filter(
|
|
293
273
|
(p) =>
|
|
@@ -35,23 +35,26 @@ function buildExportsForMultiClient(
|
|
|
35
35
|
delete packageInfo.exports["./api"];
|
|
36
36
|
}
|
|
37
37
|
if (emitterOptions.options.hierarchyClient) {
|
|
38
|
-
for
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
// TODO: support api subpath exports for multi-service. Skip for now. https://github.com/Azure/autorest.typescript/issues/3717
|
|
39
|
+
if (!emitterOptions.options.isMultiService) {
|
|
40
|
+
for (const flattenedClient of clientMap) {
|
|
41
|
+
const { subfolder } = getModularClientOptions(flattenedClient);
|
|
42
|
+
const client = flattenedClient[1];
|
|
43
|
+
const methodMap = getMethodHierarchiesMap(context, client);
|
|
44
|
+
for (const [prefixKey, _] of methodMap) {
|
|
45
|
+
const prefixes = prefixKey.split("/");
|
|
46
|
+
if (prefixKey === "") {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const subApiPath = `api/${getClassicalLayerPrefix(
|
|
50
|
+
prefixes,
|
|
51
|
+
NameType.File,
|
|
52
|
+
"/"
|
|
53
|
+
)}`;
|
|
54
|
+
packageInfo.exports[
|
|
55
|
+
`./${subfolder ? subfolder + "/" : ""}${subApiPath}`
|
|
56
|
+
] = `src/${subfolder ? subfolder + "/" : ""}${subApiPath}/index.ts`;
|
|
46
57
|
}
|
|
47
|
-
const subApiPath = `api/${getClassicalLayerPrefix(
|
|
48
|
-
prefixes,
|
|
49
|
-
NameType.File,
|
|
50
|
-
"/"
|
|
51
|
-
)}`;
|
|
52
|
-
packageInfo.exports[
|
|
53
|
-
`./${subfolder ? subfolder + "/" : ""}${subApiPath}`
|
|
54
|
-
] = `src/${subfolder ? subfolder + "/" : ""}${subApiPath}/index.ts`;
|
|
55
58
|
}
|
|
56
59
|
}
|
|
57
60
|
delete packageInfo.exports["./models"];
|
|
@@ -111,6 +111,7 @@ export function buildRestorePoller(
|
|
|
111
111
|
\`Please ensure the operation is in this client! We can't find its deserializeHelper for \${sourceOperation?.name}.\`
|
|
112
112
|
);
|
|
113
113
|
}
|
|
114
|
+
const apiVersion = getApiVersionFromUrl(initialRequestUrl);
|
|
114
115
|
return ${resolveReference(PollingHelpers.GetLongRunningPoller)}(
|
|
115
116
|
(client as any)["_client"] ?? client,
|
|
116
117
|
deserializeHelper as (result: TResponse) => Promise<TResult>,
|
|
@@ -120,7 +121,8 @@ export function buildRestorePoller(
|
|
|
120
121
|
abortSignal: options?.abortSignal,
|
|
121
122
|
resourceLocationConfig,
|
|
122
123
|
restoreFrom: serializedState,
|
|
123
|
-
initialRequestUrl
|
|
124
|
+
initialRequestUrl,
|
|
125
|
+
apiVersion,
|
|
124
126
|
}
|
|
125
127
|
);
|
|
126
128
|
}
|
|
@@ -209,7 +211,12 @@ export function buildRestorePoller(
|
|
|
209
211
|
function getPathFromMapKey(mapKey: string): string {
|
|
210
212
|
const pathStart = mapKey.indexOf("/");
|
|
211
213
|
return mapKey.slice(pathStart);
|
|
212
|
-
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function getApiVersionFromUrl(urlStr: string): string | undefined {
|
|
217
|
+
const url = new URL(urlStr);
|
|
218
|
+
return url.searchParams.get("api-version") ?? undefined;
|
|
219
|
+
}
|
|
213
220
|
`;
|
|
214
221
|
restorePollerFile.addStatements(restorePollerHelperContent);
|
|
215
222
|
}
|
|
@@ -216,6 +216,10 @@ function emitType(context: SdkContext, type: SdkType, sourceFile: SourceFile) {
|
|
|
216
216
|
return;
|
|
217
217
|
}
|
|
218
218
|
const apiVersionEnumOnly = type.usage === UsageFlags.ApiVersionEnum;
|
|
219
|
+
// Skip known api version enums for multi-service scenarios as users are not allowed to set api versions
|
|
220
|
+
if (apiVersionEnumOnly && context.rlcOptions?.isMultiService) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
219
223
|
const inputUsage = (type.usage & UsageFlags.Input) === UsageFlags.Input;
|
|
220
224
|
const outputUsage = (type.usage & UsageFlags.Output) === UsageFlags.Output;
|
|
221
225
|
const exceptionUsage =
|
|
@@ -266,6 +270,10 @@ function emitType(context: SdkContext, type: SdkType, sourceFile: SourceFile) {
|
|
|
266
270
|
}
|
|
267
271
|
|
|
268
272
|
export function getApiVersionEnum(context: SdkContext) {
|
|
273
|
+
// Skip api version enum for multi-service scenarios since each service may have different versions
|
|
274
|
+
if (context.rlcOptions?.isMultiService) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
269
277
|
const apiVersionEnum = context.sdkPackage.enums.find(
|
|
270
278
|
(e) => e.usage === UsageFlags.ApiVersionEnum
|
|
271
279
|
);
|
|
@@ -293,9 +301,6 @@ export function getModelNamespaces(
|
|
|
293
301
|
context: SdkContext,
|
|
294
302
|
model: SdkType
|
|
295
303
|
): string[] {
|
|
296
|
-
const deepestNamespace = getNamespaceFullName(
|
|
297
|
-
listAllServiceNamespaces(context)[0]!
|
|
298
|
-
);
|
|
299
304
|
if (
|
|
300
305
|
model.kind === "model" ||
|
|
301
306
|
model.kind === "enum" ||
|
|
@@ -312,6 +317,14 @@ export function getModelNamespaces(
|
|
|
312
317
|
return [];
|
|
313
318
|
}
|
|
314
319
|
const segments = model.namespace.split(".");
|
|
320
|
+
// Keep full namespace segments if multiple services are present because there isn't a root namespace to trim
|
|
321
|
+
if (context.rlcOptions?.isMultiService) {
|
|
322
|
+
return segments;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const allServiceNamespaces =
|
|
326
|
+
context.allServiceNamespaces ?? listAllServiceNamespaces(context);
|
|
327
|
+
const deepestNamespace = getNamespaceFullName(allServiceNamespaces[0]!);
|
|
315
328
|
const rootNamespace = deepestNamespace.split(".") ?? [];
|
|
316
329
|
if (segments.length > rootNamespace.length) {
|
|
317
330
|
while (segments[0] === rootNamespace[0]) {
|
|
@@ -38,7 +38,12 @@ import {
|
|
|
38
38
|
ServiceOperation
|
|
39
39
|
} from "../utils/operationUtil.js";
|
|
40
40
|
import { getSubscriptionId } from "../transform/transfromRLCOptions.js";
|
|
41
|
-
import {
|
|
41
|
+
import {
|
|
42
|
+
getClientParametersDeclaration,
|
|
43
|
+
getClientParameters,
|
|
44
|
+
hasDefaultValue,
|
|
45
|
+
getClientParameterName
|
|
46
|
+
} from "./helpers/clientHelpers.js";
|
|
42
47
|
import { getOperationFunction } from "./helpers/operationHelpers.js";
|
|
43
48
|
import { ModelOverrideOptions } from "./serialization/serializeUtils.js";
|
|
44
49
|
|
|
@@ -298,6 +303,12 @@ function prepareExampleParameters(
|
|
|
298
303
|
// TODO: blocked by TCGC issue: https://github.com/Azure/typespec-azure/issues/1419
|
|
299
304
|
// refine this to support generic client-level parameters once resolved
|
|
300
305
|
const result: ExampleValue[] = [];
|
|
306
|
+
|
|
307
|
+
// Get the raw SDK parameters to check for default values
|
|
308
|
+
const rawClientParams = getClientParameters(topLevelClient, dpgContext, {
|
|
309
|
+
onClientOnly: true
|
|
310
|
+
});
|
|
311
|
+
|
|
301
312
|
const clientParams = getClientParametersDeclaration(
|
|
302
313
|
topLevelClient,
|
|
303
314
|
dpgContext,
|
|
@@ -306,11 +317,27 @@ function prepareExampleParameters(
|
|
|
306
317
|
}
|
|
307
318
|
);
|
|
308
319
|
|
|
320
|
+
// Helper to check if a parameter has a default value
|
|
321
|
+
const hasParamDefaultValue = (paramName: string) => {
|
|
322
|
+
const rawParam = rawClientParams.find((p) => {
|
|
323
|
+
return getClientParameterName(p) === paramName;
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
if (!rawParam) return false;
|
|
327
|
+
|
|
328
|
+
return hasDefaultValue(rawParam);
|
|
329
|
+
};
|
|
330
|
+
|
|
309
331
|
for (const param of clientParams) {
|
|
310
332
|
if (param.name === "options" || param.name === "credential") {
|
|
311
333
|
continue;
|
|
312
334
|
}
|
|
313
335
|
|
|
336
|
+
// Skip parameters that have default values - they are truly optional
|
|
337
|
+
if (hasParamDefaultValue(param.name)) {
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
|
|
314
341
|
const exampleValue: ExampleValue = {
|
|
315
342
|
name: param.name === "endpointParam" ? "endpoint" : param.name,
|
|
316
343
|
value: getEnvironmentVariableName(
|
|
@@ -517,6 +544,7 @@ function getParameterValue(
|
|
|
517
544
|
switch (value.kind) {
|
|
518
545
|
case "string": {
|
|
519
546
|
switch (value.type.kind) {
|
|
547
|
+
case "plainDate":
|
|
520
548
|
case "utcDateTime":
|
|
521
549
|
retValue = `new Date("${value.value}")`;
|
|
522
550
|
break;
|
|
@@ -40,6 +40,28 @@ type SdkParameter =
|
|
|
40
40
|
| SdkCredentialParameter
|
|
41
41
|
| SdkHttpParameter;
|
|
42
42
|
|
|
43
|
+
export function hasDefaultValue(p: SdkParameter) {
|
|
44
|
+
if (
|
|
45
|
+
p.clientDefaultValue ||
|
|
46
|
+
p.__raw?.defaultValue ||
|
|
47
|
+
p.type.kind === "constant"
|
|
48
|
+
) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Special case for endpoint parameters with template arguments that have default values
|
|
53
|
+
if (p.type.kind === "endpoint" && p.type.templateArguments[0]) {
|
|
54
|
+
const templateArg = p.type.templateArguments[0];
|
|
55
|
+
return !!(
|
|
56
|
+
templateArg.clientDefaultValue ||
|
|
57
|
+
templateArg.__raw?.defaultValue ||
|
|
58
|
+
templateArg.type?.kind === "constant"
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
|
|
43
65
|
export function getClientParameters(
|
|
44
66
|
client: SdkClientType<SdkServiceOperation>,
|
|
45
67
|
dpgContext: SdkContext,
|
|
@@ -70,23 +92,22 @@ export function getClientParameters(
|
|
|
70
92
|
}
|
|
71
93
|
}
|
|
72
94
|
|
|
73
|
-
const hasDefaultValue = (p: SdkParameter) =>
|
|
74
|
-
p.clientDefaultValue || p.__raw?.defaultValue || p.type.kind === "constant";
|
|
75
95
|
const isRequired = (p: SdkParameter) =>
|
|
76
96
|
// Special case: when apiVersionAsRequired is true, apiVersion should always be considered required
|
|
77
97
|
(options.apiVersionAsRequired && p.isApiVersionParam) ||
|
|
78
|
-
(!p.optional &&
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
));
|
|
85
|
-
const isOptional = (p: SdkParameter) => p.optional || hasDefaultValue(p);
|
|
98
|
+
(!p.optional && !hasDefaultValue(p));
|
|
99
|
+
const isOptional = (p: SdkParameter) =>
|
|
100
|
+
p.optional ||
|
|
101
|
+
p.clientDefaultValue ||
|
|
102
|
+
p.__raw?.defaultValue ||
|
|
103
|
+
p.type.kind === "constant";
|
|
86
104
|
const skipCredentials = (p: SdkParameter) => p.kind !== "credential";
|
|
87
105
|
const skipMethodParam = (p: SdkParameter) => p.kind !== "method";
|
|
88
106
|
const armSpecific = (p: SdkParameter) =>
|
|
89
107
|
!(p.kind === "endpoint" && dpgContext.arm);
|
|
108
|
+
// Skip apiVersion parameter when it's multi-service (each service has its own default apiVersion)
|
|
109
|
+
const skipApiVersionOnMultiService = (p: SdkParameter) =>
|
|
110
|
+
!(dpgContext.rlcOptions?.isMultiService && p.isApiVersionParam);
|
|
90
111
|
const filters = [
|
|
91
112
|
options.requiredOnly ? isRequired : undefined,
|
|
92
113
|
dpgContext.rlcOptions?.addCredentials === false
|
|
@@ -94,7 +115,8 @@ export function getClientParameters(
|
|
|
94
115
|
: undefined,
|
|
95
116
|
options.optionalOnly ? isOptional : undefined,
|
|
96
117
|
options.onClientOnly ? skipMethodParam : undefined,
|
|
97
|
-
options.skipArmSpecific ? undefined : armSpecific
|
|
118
|
+
options.skipArmSpecific ? undefined : armSpecific,
|
|
119
|
+
skipApiVersionOnMultiService
|
|
98
120
|
];
|
|
99
121
|
const params = clientParams.filter((p) =>
|
|
100
122
|
filters.every((filter) => !filter || filter(p))
|
|
@@ -70,7 +70,6 @@ import {
|
|
|
70
70
|
isHttpMetadata,
|
|
71
71
|
isReadOnly,
|
|
72
72
|
SdkBodyParameter,
|
|
73
|
-
SdkClientType,
|
|
74
73
|
SdkConstantType,
|
|
75
74
|
SdkEnumType,
|
|
76
75
|
SdkHttpOperation,
|
|
@@ -90,7 +89,6 @@ import { isExtensibleEnum } from "../type-expressions/get-enum-expression.js";
|
|
|
90
89
|
|
|
91
90
|
export function getSendPrivateFunction(
|
|
92
91
|
dpgContext: SdkContext,
|
|
93
|
-
client: SdkClientType<SdkHttpOperation>,
|
|
94
92
|
method: [string[], ServiceOperation],
|
|
95
93
|
clientType: string
|
|
96
94
|
): OptionalKind<FunctionDeclarationStructure> {
|
|
@@ -114,12 +112,6 @@ export function getSendPrivateFunction(
|
|
|
114
112
|
const operationPath = operation.operation.path;
|
|
115
113
|
const operationMethod = operation.operation.verb.toLowerCase();
|
|
116
114
|
const optionalParamName = getOptionalParamsName(parameters);
|
|
117
|
-
const hasQueryApiVersion = operation.operation.parameters.some(
|
|
118
|
-
(p) => p.onClient && p.kind === "query" && p.isApiVersionParam
|
|
119
|
-
);
|
|
120
|
-
const hasClientApiVersion = client.clientInitialization.parameters.some(
|
|
121
|
-
(p) => p.isApiVersionParam && p.onClient && p.kind === "method"
|
|
122
|
-
);
|
|
123
115
|
const statements: string[] = [];
|
|
124
116
|
let pathStr = `"${operationPath}"`;
|
|
125
117
|
const urlTemplateParams = [
|
|
@@ -134,11 +126,6 @@ export function getSendPrivateFunction(
|
|
|
134
126
|
});`);
|
|
135
127
|
pathStr = "path";
|
|
136
128
|
}
|
|
137
|
-
if (hasClientApiVersion && !hasQueryApiVersion) {
|
|
138
|
-
statements.push(
|
|
139
|
-
`context.pipeline.removePolicy({ name: "ClientApiVersionPolicy"});`
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
129
|
|
|
143
130
|
statements.push(
|
|
144
131
|
`return context.path(${pathStr}).${operationMethod}({...${resolveReference(dependencies.operationOptionsToRequestParameters)}(${optionalParamName}), ${getHeaderAndBodyParameters(
|
|
@@ -684,9 +671,11 @@ function getLroOnlyOperationFunction(
|
|
|
684
671
|
const resourceLocationConfig =
|
|
685
672
|
lroMetadata?.finalStateVia &&
|
|
686
673
|
allowedFinalLocation.includes(lroMetadata?.finalStateVia)
|
|
687
|
-
? `resourceLocationConfig: "${lroMetadata?.finalStateVia}"
|
|
674
|
+
? `resourceLocationConfig: "${lroMetadata?.finalStateVia}",`
|
|
688
675
|
: "";
|
|
676
|
+
const apiVersion = getApiVersionExpression(context, operation);
|
|
689
677
|
const statements: string[] = [];
|
|
678
|
+
|
|
690
679
|
statements.push(`
|
|
691
680
|
|
|
692
681
|
return ${getLongRunningPollerReference}(context, _${name}Deserialize, ${getExpectedStatuses(
|
|
@@ -698,6 +687,7 @@ function getLroOnlyOperationFunction(
|
|
|
698
687
|
.map((p) => p.name)
|
|
699
688
|
.join(", ")}),
|
|
700
689
|
${resourceLocationConfig}
|
|
690
|
+
${apiVersion ? `apiVersion: ${apiVersion}` : ""}
|
|
701
691
|
}) as ${pollerLikeReference}<${operationStateReference}<${
|
|
702
692
|
returnType.type
|
|
703
693
|
}>, ${returnType.type}>;
|
|
@@ -725,6 +715,9 @@ function getLroAndPagingOperationFunction(
|
|
|
725
715
|
|
|
726
716
|
const returnType = buildLroPagingReturnType(context, operation);
|
|
727
717
|
|
|
718
|
+
// Get apiVersion expression for both LRO poller and paging options
|
|
719
|
+
const apiVersion = getApiVersionExpression(context, operation);
|
|
720
|
+
|
|
728
721
|
// Build paging options from metadata
|
|
729
722
|
const pagingOptions = [
|
|
730
723
|
operation.response.resultSegments &&
|
|
@@ -732,7 +725,8 @@ function getLroAndPagingOperationFunction(
|
|
|
732
725
|
operation.pagingMetadata.nextLinkSegments &&
|
|
733
726
|
`nextLinkName: "${operation.pagingMetadata.nextLinkSegments.map((p) => p.name).join(".")}"`,
|
|
734
727
|
operation.pagingMetadata.nextLinkVerb !== "GET" &&
|
|
735
|
-
`nextLinkMethod: "${operation.pagingMetadata.nextLinkVerb}"
|
|
728
|
+
`nextLinkMethod: "${operation.pagingMetadata.nextLinkVerb}"`,
|
|
729
|
+
apiVersion && `apiVersion: ${apiVersion}`
|
|
736
730
|
].filter(Boolean);
|
|
737
731
|
|
|
738
732
|
// Build LRO resource location config
|
|
@@ -745,7 +739,7 @@ function getLroAndPagingOperationFunction(
|
|
|
745
739
|
const resourceLocationConfig =
|
|
746
740
|
operation.lroMetadata?.finalStateVia &&
|
|
747
741
|
allowedLocations.includes(operation.lroMetadata.finalStateVia)
|
|
748
|
-
? `resourceLocationConfig: "${operation.lroMetadata.finalStateVia}"
|
|
742
|
+
? `resourceLocationConfig: "${operation.lroMetadata.finalStateVia}",`
|
|
749
743
|
: "";
|
|
750
744
|
|
|
751
745
|
// Resolve references
|
|
@@ -784,6 +778,7 @@ function getLroAndPagingOperationFunction(
|
|
|
784
778
|
abortSignal: ${optionalParamName}?.abortSignal,
|
|
785
779
|
getInitialResponse: () => _${name}Send(${paramList}),
|
|
786
780
|
${resourceLocationConfig}
|
|
781
|
+
${apiVersion ? `apiVersion: ${apiVersion}` : ""}
|
|
787
782
|
}) as ${refs.pollerLike}<${refs.operationState}<${refs.pathResponse}>, ${refs.pathResponse}>;
|
|
788
783
|
|
|
789
784
|
return ${refs.buildPaging}(
|
|
@@ -887,6 +882,8 @@ function getPagingOnlyOperationFunction(
|
|
|
887
882
|
// Check for nextLinkVerb from TCGC pagingMetadata (supports @Legacy.nextLinkVerb decorator)
|
|
888
883
|
const nextLinkMethod = operation.pagingMetadata.nextLinkVerb;
|
|
889
884
|
|
|
885
|
+
const apiVersion = getApiVersionExpression(context, operation);
|
|
886
|
+
|
|
890
887
|
if (itemName) {
|
|
891
888
|
options.push(`itemName: "${itemName}"`);
|
|
892
889
|
}
|
|
@@ -896,6 +893,9 @@ function getPagingOnlyOperationFunction(
|
|
|
896
893
|
if (nextLinkMethod && nextLinkMethod !== "GET") {
|
|
897
894
|
options.push(`nextLinkMethod: "${nextLinkMethod}"`);
|
|
898
895
|
}
|
|
896
|
+
if (apiVersion) {
|
|
897
|
+
options.push(`apiVersion: ${apiVersion}`);
|
|
898
|
+
}
|
|
899
899
|
statements.push(
|
|
900
900
|
`return ${buildPagedAsyncIteratorReference}(
|
|
901
901
|
context,
|
|
@@ -1151,6 +1151,15 @@ export function getParameterMap(
|
|
|
1151
1151
|
return `"${serializedName}": ${getConstantValue(param.type)}`;
|
|
1152
1152
|
}
|
|
1153
1153
|
|
|
1154
|
+
// Special case for api-version parameters with default values
|
|
1155
|
+
if (param.isApiVersionParam && param.clientDefaultValue) {
|
|
1156
|
+
// For multi-service, use only the default value (don't reference context.apiVersion)
|
|
1157
|
+
if (context.rlcOptions?.isMultiService) {
|
|
1158
|
+
return `"${serializedName}": "${param.clientDefaultValue}"`;
|
|
1159
|
+
}
|
|
1160
|
+
return `"${serializedName}": ${param.onClient ? "context." : ""}${param.name} ?? "${param.clientDefaultValue}"`;
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1154
1163
|
if (hasCollectionFormatInfo(param.kind, (param as any).collectionFormat)) {
|
|
1155
1164
|
return getCollectionFormatForParam(
|
|
1156
1165
|
context,
|
|
@@ -1722,6 +1731,9 @@ export function serializeRequestValue(
|
|
|
1722
1731
|
? `!${clientValue}? ${clientValue}: `
|
|
1723
1732
|
: "";
|
|
1724
1733
|
switch (type.kind) {
|
|
1734
|
+
case "plainDate":
|
|
1735
|
+
// plainDate always uses ISO8601 format (YYYY-MM-DD)
|
|
1736
|
+
return `${nullOrUndefinedPrefix}${clientValue}.toISOString().split('T')[0]`;
|
|
1725
1737
|
case "utcDateTime":
|
|
1726
1738
|
switch (type.encode ?? format) {
|
|
1727
1739
|
case "rfc7231":
|
|
@@ -1849,6 +1861,9 @@ export function deserializeResponseValue(
|
|
|
1849
1861
|
? `!${restValue}? ${restValue}: `
|
|
1850
1862
|
: "";
|
|
1851
1863
|
switch (type.kind) {
|
|
1864
|
+
case "plainDate":
|
|
1865
|
+
// plainDate deserializes from YYYY-MM-DD string to Date
|
|
1866
|
+
return `${nullOrUndefinedPrefix} new Date(${restValue})`;
|
|
1852
1867
|
case "utcDateTime":
|
|
1853
1868
|
return `${nullOrUndefinedPrefix} new Date(${type.encode === "unixTimestamp" ? `${restValue} * 1000` : restValue})`;
|
|
1854
1869
|
case "array": {
|
|
@@ -2088,3 +2103,32 @@ export function getExpectedStatuses(operation: ServiceOperation): string {
|
|
|
2088
2103
|
|
|
2089
2104
|
return `[${statusCodes.map((x) => `"${x}"`).join(", ")}]`;
|
|
2090
2105
|
}
|
|
2106
|
+
|
|
2107
|
+
/**
|
|
2108
|
+
* Gets the apiVersion expression with default value fallback for query parameters.
|
|
2109
|
+
* @param dpgContext - The SDK context
|
|
2110
|
+
* @param operation - The operation to get the apiVersion parameter from
|
|
2111
|
+
* @returns The apiVersion expression string, or undefined if no apiVersion query param exists
|
|
2112
|
+
*/
|
|
2113
|
+
function getApiVersionExpression(
|
|
2114
|
+
dpgContext: SdkContext,
|
|
2115
|
+
operation: ServiceOperation
|
|
2116
|
+
): string | undefined {
|
|
2117
|
+
const queryApiVersionParam = operation.operation.parameters.find(
|
|
2118
|
+
(p) => p.kind === "query" && p.isApiVersionParam
|
|
2119
|
+
);
|
|
2120
|
+
if (!queryApiVersionParam) {
|
|
2121
|
+
return undefined;
|
|
2122
|
+
}
|
|
2123
|
+
// For multi-service, use only the default value (don't reference context.apiVersion)
|
|
2124
|
+
if (dpgContext.rlcOptions?.isMultiService) {
|
|
2125
|
+
return queryApiVersionParam.clientDefaultValue
|
|
2126
|
+
? `"${queryApiVersionParam.clientDefaultValue}"`
|
|
2127
|
+
: undefined;
|
|
2128
|
+
}
|
|
2129
|
+
const paramAccess = `${queryApiVersionParam.onClient ? "context." : ""}${queryApiVersionParam.name}`;
|
|
2130
|
+
const defaultValueSuffix = queryApiVersionParam.clientDefaultValue
|
|
2131
|
+
? ` ?? "${queryApiVersionParam.clientDefaultValue}"`
|
|
2132
|
+
: "";
|
|
2133
|
+
return `${paramAccess}${defaultValueSuffix}`;
|
|
2134
|
+
}
|
|
@@ -78,7 +78,7 @@ const NumericTypeKinds = [
|
|
|
78
78
|
"decimal128"
|
|
79
79
|
];
|
|
80
80
|
|
|
81
|
-
const DateTimeTypeKinds = ["
|
|
81
|
+
const DateTimeTypeKinds = ["plainTime"];
|
|
82
82
|
|
|
83
83
|
// This may be a good candidate to move to TCGC
|
|
84
84
|
export function isNumericTypeKind(kind: string): boolean {
|
|
@@ -178,7 +178,11 @@ function buildPolymorphicDeserializer(
|
|
|
178
178
|
|
|
179
179
|
const subTypes = type.discriminatedSubtypes;
|
|
180
180
|
if (!subTypes) {
|
|
181
|
-
|
|
181
|
+
// No subtypes - treat as a regular model and generate simple deserializer
|
|
182
|
+
return buildModelTypeDeserializer(context, type, {
|
|
183
|
+
nameOnly,
|
|
184
|
+
skipDiscriminatedUnionSuffix: false
|
|
185
|
+
});
|
|
182
186
|
}
|
|
183
187
|
|
|
184
188
|
const cases: string[] = [];
|
|
@@ -184,7 +184,11 @@ function buildPolymorphicSerializer(
|
|
|
184
184
|
|
|
185
185
|
const subTypes = type.discriminatedSubtypes;
|
|
186
186
|
if (!subTypes) {
|
|
187
|
-
|
|
187
|
+
// No subtypes - treat as a regular model and generate simple serializer
|
|
188
|
+
return buildModelTypeSerializer(context, type, {
|
|
189
|
+
nameOnly,
|
|
190
|
+
skipDiscriminatedUnionSuffix: false
|
|
191
|
+
});
|
|
188
192
|
}
|
|
189
193
|
|
|
190
194
|
const cases: string[] = [];
|
|
@@ -62,7 +62,6 @@ export function getTypeExpression(
|
|
|
62
62
|
}
|
|
63
63
|
return "number";
|
|
64
64
|
case "endpoint":
|
|
65
|
-
case "plainDate":
|
|
66
65
|
case "plainTime":
|
|
67
66
|
case "string":
|
|
68
67
|
case "url":
|
|
@@ -103,6 +102,7 @@ export function getTypeExpression(
|
|
|
103
102
|
case "union":
|
|
104
103
|
return getUnionExpression(context, type, options);
|
|
105
104
|
case "utcDateTime":
|
|
105
|
+
case "plainDate":
|
|
106
106
|
return "Date";
|
|
107
107
|
|
|
108
108
|
default:
|
|
@@ -58,7 +58,7 @@ export async function transformRLCModel(
|
|
|
58
58
|
? client.name
|
|
59
59
|
: (options?.title ??
|
|
60
60
|
client.name ??
|
|
61
|
-
getDefaultService(program)?.title ??
|
|
61
|
+
getDefaultService(program, options.isModularLibrary)?.title ??
|
|
62
62
|
""),
|
|
63
63
|
NameType.Class
|
|
64
64
|
);
|
|
@@ -123,7 +123,10 @@ export function transformUrlInfo(
|
|
|
123
123
|
const importedModels = new Set<string>();
|
|
124
124
|
const usage = [SchemaContext.Exception, SchemaContext.Input];
|
|
125
125
|
const program = dpgContext.program;
|
|
126
|
-
const serviceNs = getDefaultService(
|
|
126
|
+
const serviceNs = getDefaultService(
|
|
127
|
+
program,
|
|
128
|
+
dpgContext.rlcOptions?.isModularLibrary
|
|
129
|
+
)?.type;
|
|
127
130
|
let endpoint = undefined;
|
|
128
131
|
const urlParameters: PathParameter[] = [];
|
|
129
132
|
if (serviceNs) {
|