@azure-tools/typespec-ts 0.48.0 → 0.48.1-alpha.20260127.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 +14 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +20 -5
- package/dist/src/index.js.map +1 -1
- package/dist/src/modular/buildClientContext.d.ts.map +1 -1
- package/dist/src/modular/buildClientContext.js +7 -3
- 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 +24 -3
- package/dist/src/modular/buildOperations.js.map +1 -1
- package/dist/src/modular/emitModels.d.ts.map +1 -1
- package/dist/src/modular/emitModels.js +19 -0
- package/dist/src/modular/emitModels.js.map +1 -1
- package/dist/src/modular/emitSamples.js +2 -2
- package/dist/src/modular/emitSamples.js.map +1 -1
- package/dist/src/modular/helpers/clientHelpers.d.ts +2 -1
- package/dist/src/modular/helpers/clientHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/clientHelpers.js +5 -2
- package/dist/src/modular/helpers/clientHelpers.js.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.js +266 -43
- package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
- package/dist/src/modular/serialization/buildXmlSerializerFunction.d.ts +32 -0
- package/dist/src/modular/serialization/buildXmlSerializerFunction.d.ts.map +1 -0
- package/dist/src/modular/serialization/buildXmlSerializerFunction.js +373 -0
- package/dist/src/modular/serialization/buildXmlSerializerFunction.js.map +1 -0
- package/dist/src/modular/static-helpers-metadata.d.ts +57 -0
- package/dist/src/modular/static-helpers-metadata.d.ts.map +1 -1
- package/dist/src/modular/static-helpers-metadata.js +57 -0
- package/dist/src/modular/static-helpers-metadata.js.map +1 -1
- package/dist/src/utils/clientUtils.d.ts.map +1 -1
- package/dist/src/utils/clientUtils.js +1 -0
- package/dist/src/utils/clientUtils.js.map +1 -1
- package/dist/src/utils/mediaTypes.d.ts +4 -0
- package/dist/src/utils/mediaTypes.d.ts.map +1 -1
- package/dist/src/utils/mediaTypes.js +10 -0
- package/dist/src/utils/mediaTypes.js.map +1 -1
- package/dist/src/utils/modelUtils.d.ts.map +1 -1
- package/dist/src/utils/modelUtils.js +3 -0
- package/dist/src/utils/modelUtils.js.map +1 -1
- package/dist/src/utils/operationUtil.d.ts +12 -0
- package/dist/src/utils/operationUtil.d.ts.map +1 -1
- package/dist/src/utils/operationUtil.js +22 -1
- package/dist/src/utils/operationUtil.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -7
- package/src/index.ts +20 -5
- package/src/modular/buildClientContext.ts +12 -5
- package/src/modular/buildOperations.ts +34 -3
- package/src/modular/emitModels.ts +43 -0
- package/src/modular/emitSamples.ts +2 -2
- package/src/modular/helpers/clientHelpers.ts +6 -2
- package/src/modular/helpers/operationHelpers.ts +377 -57
- package/src/modular/serialization/buildXmlSerializerFunction.ts +511 -0
- package/src/modular/static-helpers-metadata.ts +58 -0
- package/src/utils/clientUtils.ts +1 -0
- package/src/utils/mediaTypes.ts +12 -0
- package/src/utils/modelUtils.ts +3 -0
- package/src/utils/operationUtil.ts +34 -1
- package/static/static-helpers/serialization/xml-helpers.ts +596 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@azure-tools/typespec-ts",
|
|
3
|
-
"version": "0.48.
|
|
3
|
+
"version": "0.48.1-alpha.20260127.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.
|
|
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,8 @@
|
|
|
73
73
|
"@typespec/xml": "^0.78.0"
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
|
-
"@azure-tools/rlc-common": "
|
|
76
|
+
"@azure-tools/rlc-common": "0.48.1-alpha.20260127.1",
|
|
77
|
+
"fast-xml-parser": "^4.5.0",
|
|
77
78
|
"fs-extra": "^11.1.0",
|
|
78
79
|
"lodash": "^4.17.21",
|
|
79
80
|
"prettier": "^3.3.3",
|
package/src/index.ts
CHANGED
|
@@ -18,7 +18,8 @@ import {
|
|
|
18
18
|
PollingHelpers,
|
|
19
19
|
SerializationHelpers,
|
|
20
20
|
SimplePollerHelpers,
|
|
21
|
-
UrlTemplateHelpers
|
|
21
|
+
UrlTemplateHelpers,
|
|
22
|
+
XmlHelpers
|
|
22
23
|
} from "./modular/static-helpers-metadata.js";
|
|
23
24
|
import {
|
|
24
25
|
RLCModel,
|
|
@@ -92,6 +93,7 @@ import { getModuleExports } from "./modular/buildProjectFiles.js";
|
|
|
92
93
|
import { getClientHierarchyMap, getRLCClients } from "./utils/clientUtils.js";
|
|
93
94
|
import { join } from "path";
|
|
94
95
|
import { loadStaticHelpers } from "./framework/load-static-helpers.js";
|
|
96
|
+
import { packageUsesXmlSerialization } from "./modular/serialization/buildXmlSerializerFunction.js";
|
|
95
97
|
import { provideBinder } from "./framework/hooks/binder.js";
|
|
96
98
|
import { provideSdkTypes } from "./framework/hooks/sdkTypes.js";
|
|
97
99
|
import { transformRLCModel } from "./transform/transform.js";
|
|
@@ -135,7 +137,8 @@ export async function $onEmit(context: EmitContext) {
|
|
|
135
137
|
...SimplePollerHelpers,
|
|
136
138
|
...UrlTemplateHelpers,
|
|
137
139
|
...MultipartHelpers,
|
|
138
|
-
...CloudSettingHelpers
|
|
140
|
+
...CloudSettingHelpers,
|
|
141
|
+
...XmlHelpers
|
|
139
142
|
},
|
|
140
143
|
{
|
|
141
144
|
sourcesDir: dpgContext.generationPathDetail?.modularSourcesDir,
|
|
@@ -479,17 +482,29 @@ export async function $onEmit(context: EmitContext) {
|
|
|
479
482
|
modularPackageInfo = {
|
|
480
483
|
exports: getModuleExports(context, modularEmitterOptions)
|
|
481
484
|
};
|
|
485
|
+
// Build dependencies
|
|
486
|
+
const dependencies: Record<string, string> = {};
|
|
487
|
+
if (isAzureFlavor) {
|
|
488
|
+
dependencies["@azure/core-util"] = "^1.9.2";
|
|
489
|
+
}
|
|
490
|
+
// Add fast-xml-parser if XML serialization is used
|
|
491
|
+
if (packageUsesXmlSerialization(dpgContext.sdkPackage)) {
|
|
492
|
+
dependencies["fast-xml-parser"] = "^4.5.0";
|
|
493
|
+
}
|
|
482
494
|
if (isAzureFlavor) {
|
|
483
495
|
modularPackageInfo = {
|
|
484
496
|
...modularPackageInfo,
|
|
485
|
-
dependencies
|
|
486
|
-
"@azure/core-util": "^1.9.2"
|
|
487
|
-
},
|
|
497
|
+
dependencies,
|
|
488
498
|
clientContextPaths: getRelativeContextPaths(
|
|
489
499
|
context,
|
|
490
500
|
modularEmitterOptions
|
|
491
501
|
)
|
|
492
502
|
};
|
|
503
|
+
} else if (Object.keys(dependencies).length > 0) {
|
|
504
|
+
modularPackageInfo = {
|
|
505
|
+
...modularPackageInfo,
|
|
506
|
+
dependencies
|
|
507
|
+
};
|
|
493
508
|
}
|
|
494
509
|
}
|
|
495
510
|
commonBuilders.push((model) =>
|
|
@@ -200,10 +200,20 @@ export function buildClientContext(
|
|
|
200
200
|
const { endpointParamName: endpointParam, assignedOptionalParams } =
|
|
201
201
|
buildGetClientEndpointParam(factoryFunction, dpgContext, client);
|
|
202
202
|
const credentialParam = buildGetClientCredentialParam(client, emitterOptions);
|
|
203
|
+
|
|
204
|
+
// Get api version param early so we can use its name when building options
|
|
205
|
+
const apiVersionParam = getClientParameters(client, dpgContext).find(
|
|
206
|
+
(x) => x.isApiVersionParam
|
|
207
|
+
);
|
|
208
|
+
const apiVersionParamName = apiVersionParam
|
|
209
|
+
? getClientParameterName(apiVersionParam)
|
|
210
|
+
: undefined;
|
|
211
|
+
|
|
203
212
|
const optionsParam = buildGetClientOptionsParam(
|
|
204
213
|
factoryFunction,
|
|
205
214
|
emitterOptions,
|
|
206
|
-
endpointParam
|
|
215
|
+
endpointParam,
|
|
216
|
+
apiVersionParamName
|
|
207
217
|
);
|
|
208
218
|
|
|
209
219
|
factoryFunction.addStatements(
|
|
@@ -230,9 +240,6 @@ export function buildClientContext(
|
|
|
230
240
|
}
|
|
231
241
|
|
|
232
242
|
let apiVersionPolicyStatement = `clientContext.pipeline.removePolicy({ name: "ApiVersionPolicy" });`;
|
|
233
|
-
const apiVersionParam = getClientParameters(client, dpgContext).find(
|
|
234
|
-
(x) => x.isApiVersionParam
|
|
235
|
-
);
|
|
236
243
|
const endpointParameter = getClientParameters(client, dpgContext, {
|
|
237
244
|
onClientOnly: false,
|
|
238
245
|
requiredOnly: true,
|
|
@@ -248,7 +255,7 @@ export function buildClientContext(
|
|
|
248
255
|
const apiVersionInEndpoint =
|
|
249
256
|
templateArguments && templateArguments.find((p) => p.isApiVersionParam);
|
|
250
257
|
if (!apiVersionInEndpoint && apiVersionParam.clientDefaultValue) {
|
|
251
|
-
apiVersionPolicyStatement += `const
|
|
258
|
+
apiVersionPolicyStatement += `const ${apiVersionParamName} = options.${apiVersionParamName} ?? "${apiVersionParam.clientDefaultValue}";`;
|
|
252
259
|
}
|
|
253
260
|
|
|
254
261
|
if (apiVersionParam.kind === "method") {
|
|
@@ -11,7 +11,8 @@ import {
|
|
|
11
11
|
getOperationFunction,
|
|
12
12
|
getOperationOptionsName,
|
|
13
13
|
getSendPrivateFunction,
|
|
14
|
-
isLroOnlyOperation
|
|
14
|
+
isLroOnlyOperation,
|
|
15
|
+
isLroAndPagingOperation
|
|
15
16
|
} from "./helpers/operationHelpers.js";
|
|
16
17
|
|
|
17
18
|
import { OperationPathAndDeserDetails } from "./interfaces.js";
|
|
@@ -30,7 +31,8 @@ import {
|
|
|
30
31
|
} from "@azure-tools/typespec-client-generator-core";
|
|
31
32
|
import {
|
|
32
33
|
getMethodHierarchiesMap,
|
|
33
|
-
ServiceOperation
|
|
34
|
+
ServiceOperation,
|
|
35
|
+
hasDualFormatSupport
|
|
34
36
|
} from "../utils/operationUtil.js";
|
|
35
37
|
import { resolveReference } from "../framework/reference.js";
|
|
36
38
|
import { useDependencies } from "../framework/hooks/useDependencies.js";
|
|
@@ -144,6 +146,20 @@ export function buildOperationOptions(
|
|
|
144
146
|
docs: ["Delay to wait until next poll, in milliseconds."]
|
|
145
147
|
};
|
|
146
148
|
|
|
149
|
+
// Check if this operation supports both JSON and XML content types
|
|
150
|
+
const bodyContentTypes = operation.operation.bodyParam?.contentTypes ?? [];
|
|
151
|
+
const isDualFormat = hasDualFormatSupport(bodyContentTypes);
|
|
152
|
+
|
|
153
|
+
// Content type option for dual-format operations
|
|
154
|
+
const contentTypeOption = {
|
|
155
|
+
name: "contentType",
|
|
156
|
+
type: "string",
|
|
157
|
+
hasQuestionToken: true,
|
|
158
|
+
docs: [
|
|
159
|
+
'The content type for the request body. Defaults to "application/json". Use "application/xml" for XML serialization.'
|
|
160
|
+
]
|
|
161
|
+
};
|
|
162
|
+
|
|
147
163
|
// handle optional body parameter
|
|
148
164
|
// if (operation.operation.bodyParam?.optional === true) {
|
|
149
165
|
// options.push(operation.operation.bodyParam);
|
|
@@ -151,12 +167,27 @@ export function buildOperationOptions(
|
|
|
151
167
|
const operationOptionsReference = resolveReference(
|
|
152
168
|
dependencies.OperationOptions
|
|
153
169
|
);
|
|
170
|
+
|
|
171
|
+
// Build the additional options array
|
|
172
|
+
const additionalOptions: {
|
|
173
|
+
name: string;
|
|
174
|
+
type: string;
|
|
175
|
+
hasQuestionToken: boolean;
|
|
176
|
+
docs: string[];
|
|
177
|
+
}[] = [];
|
|
178
|
+
if (isLroOnlyOperation(operation) || isLroAndPagingOperation(operation)) {
|
|
179
|
+
additionalOptions.push(lroOptions);
|
|
180
|
+
}
|
|
181
|
+
if (isDualFormat) {
|
|
182
|
+
additionalOptions.push(contentTypeOption);
|
|
183
|
+
}
|
|
184
|
+
|
|
154
185
|
const operationOptionsInterface: InterfaceDeclarationStructure = {
|
|
155
186
|
kind: StructureKind.Interface,
|
|
156
187
|
name,
|
|
157
188
|
isExported: true,
|
|
158
189
|
extends: [operationOptionsReference],
|
|
159
|
-
properties:
|
|
190
|
+
properties: additionalOptions.concat(
|
|
160
191
|
options.map((p) => {
|
|
161
192
|
return {
|
|
162
193
|
docs: getDocsFromDescription(p.doc),
|
|
@@ -48,6 +48,11 @@ import {
|
|
|
48
48
|
buildModelSerializer,
|
|
49
49
|
buildPropertySerializer
|
|
50
50
|
} from "./serialization/buildSerializerFunction.js";
|
|
51
|
+
import {
|
|
52
|
+
buildXmlModelSerializer,
|
|
53
|
+
buildXmlModelDeserializer,
|
|
54
|
+
hasXmlSerialization
|
|
55
|
+
} from "./serialization/buildXmlSerializerFunction.js";
|
|
51
56
|
import path from "path";
|
|
52
57
|
import { refkey } from "../framework/refkey.js";
|
|
53
58
|
import { useContext } from "../contextManager.js";
|
|
@@ -334,6 +339,8 @@ function addSerializationFunctions(
|
|
|
334
339
|
nameOnly: false,
|
|
335
340
|
skipDiscriminatedUnionSuffix
|
|
336
341
|
};
|
|
342
|
+
|
|
343
|
+
// Add JSON serializers
|
|
337
344
|
const serializationFunction =
|
|
338
345
|
typeOrProperty.kind === "property"
|
|
339
346
|
? buildPropertySerializer(context, typeOrProperty, options)
|
|
@@ -359,6 +366,42 @@ function addSerializationFunctions(
|
|
|
359
366
|
) {
|
|
360
367
|
addDeclaration(sourceFile, deserializationFunction, deserializerRefKey);
|
|
361
368
|
}
|
|
369
|
+
|
|
370
|
+
// Add XML serializers if the type has XML serialization options
|
|
371
|
+
if (typeOrProperty.kind === "model" && hasXmlSerialization(typeOrProperty)) {
|
|
372
|
+
const xmlSerializerRefKey = refkey(typeOrProperty, "xmlSerializer");
|
|
373
|
+
const xmlDeserializerRefKey = refkey(typeOrProperty, "xmlDeserializer");
|
|
374
|
+
|
|
375
|
+
const xmlSerializationFunction = buildXmlModelSerializer(
|
|
376
|
+
context,
|
|
377
|
+
typeOrProperty,
|
|
378
|
+
options
|
|
379
|
+
);
|
|
380
|
+
if (
|
|
381
|
+
xmlSerializationFunction &&
|
|
382
|
+
typeof xmlSerializationFunction !== "string" &&
|
|
383
|
+
xmlSerializationFunction.name
|
|
384
|
+
) {
|
|
385
|
+
addDeclaration(sourceFile, xmlSerializationFunction, xmlSerializerRefKey);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
const xmlDeserializationFunction = buildXmlModelDeserializer(
|
|
389
|
+
context,
|
|
390
|
+
typeOrProperty,
|
|
391
|
+
options
|
|
392
|
+
);
|
|
393
|
+
if (
|
|
394
|
+
xmlDeserializationFunction &&
|
|
395
|
+
typeof xmlDeserializationFunction !== "string" &&
|
|
396
|
+
xmlDeserializationFunction.name
|
|
397
|
+
) {
|
|
398
|
+
addDeclaration(
|
|
399
|
+
sourceFile,
|
|
400
|
+
xmlDeserializationFunction,
|
|
401
|
+
xmlDeserializerRefKey
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
362
405
|
}
|
|
363
406
|
|
|
364
407
|
function buildUnionType(
|
|
@@ -281,7 +281,7 @@ function prepareExampleValue(
|
|
|
281
281
|
onClient?: boolean
|
|
282
282
|
): ExampleValue {
|
|
283
283
|
return {
|
|
284
|
-
name: normalizeName(name, NameType.Parameter),
|
|
284
|
+
name: normalizeName(name, NameType.Parameter, true),
|
|
285
285
|
value:
|
|
286
286
|
typeof value === "string" ? value : getParameterValue(context, value),
|
|
287
287
|
isOptional: Boolean(isOptional),
|
|
@@ -411,7 +411,7 @@ function prepareExampleParameters(
|
|
|
411
411
|
const bodyParam = method.operation.bodyParam;
|
|
412
412
|
const bodySerializeName = bodyParam?.serializedName;
|
|
413
413
|
const bodyExample = parameterMap[bodySerializeName ?? ""];
|
|
414
|
-
if (
|
|
414
|
+
if (bodyParam && bodyExample && bodyExample.value) {
|
|
415
415
|
if (
|
|
416
416
|
isSpreadBodyParameter(bodyParam) &&
|
|
417
417
|
bodyParam.type.kind === "model" &&
|
|
@@ -249,12 +249,14 @@ export function buildGetClientEndpointParam(
|
|
|
249
249
|
*
|
|
250
250
|
* @param context - context in which the options are being passed; statements will be added to this context
|
|
251
251
|
* to help build the options shape
|
|
252
|
+
* @param apiVersionParamName - the name of the api version parameter in options (e.g., "apiVersion" or "version")
|
|
252
253
|
* @returns - an expression representing the options to be passed in to getClient
|
|
253
254
|
*/
|
|
254
255
|
export function buildGetClientOptionsParam(
|
|
255
256
|
context: StatementedNode,
|
|
256
257
|
emitterOptions: ModularEmitterOptions,
|
|
257
|
-
endpointParam: string
|
|
258
|
+
endpointParam: string,
|
|
259
|
+
apiVersionParamName?: string
|
|
258
260
|
): string {
|
|
259
261
|
const userAgentOptions = buildUserAgentOptions(
|
|
260
262
|
context,
|
|
@@ -264,7 +266,9 @@ export function buildGetClientOptionsParam(
|
|
|
264
266
|
const loggingOptions = buildLoggingOptions(emitterOptions.options.flavor);
|
|
265
267
|
const credentials = buildCredentials(emitterOptions, endpointParam);
|
|
266
268
|
|
|
267
|
-
|
|
269
|
+
// Use the actual api version parameter name for destructuring, defaulting to "apiVersion"
|
|
270
|
+
const apiVersionDestructure = apiVersionParamName ?? "apiVersion";
|
|
271
|
+
let expr = `const { ${apiVersionDestructure}: _, ...updatedOptions } = {`;
|
|
268
272
|
|
|
269
273
|
expr += "...options,";
|
|
270
274
|
|