@@ -21,7 +21,10 @@ import {
2121 getCollectionFormatHelper ,
2222 hasCollectionFormatInfo ,
2323 isBinaryPayload ,
24- ServiceOperation
24+ ServiceOperation ,
25+ getCollectionFormatParseHelper ,
26+ getCollectionFormatFromArrayEncoding ,
27+ KnownCollectionFormat
2528} from "../../utils/operationUtil.js" ;
2629import {
2730 getPropertyWithOverrides ,
@@ -245,6 +248,7 @@ export function getDeserializePrivateFunction(
245248 context ,
246249 deserializedType ,
247250 deserializedRoot ,
251+ true ,
248252 isBinaryPayload ( context , response . type ! . __raw ! , contentTypes ! )
249253 ? "binary"
250254 : getEncodeForType ( deserializedType )
@@ -856,6 +860,7 @@ function buildBodyParameter(
856860 isBinaryPayload ( context , bodyParameter . __raw ! , bodyParameter . contentTypes )
857861 ? "binary"
858862 : getEncodeForType ( bodyParameter . type ) ,
863+ undefined ,
859864 true
860865 ) ;
861866 return `\nbody: ${ serializedBody . startsWith ( nullOrUndefinedPrefix ) ? "" : nullOrUndefinedPrefix } ${ serializedBody } ,` ;
@@ -884,7 +889,7 @@ export function getParameterMap(
884889 }
885890
886891 if ( hasCollectionFormatInfo ( param . kind , ( param as any ) . collectionFormat ) ) {
887- return getCollectionFormat ( context , param , optionalParamName ) ;
892+ return getCollectionFormatForParam ( context , param , optionalParamName ) ;
888893 }
889894
890895 // if the parameter or property is optional, we don't need to handle the default value
@@ -909,39 +914,22 @@ export function getParameterMap(
909914 return `"${ param . name } ": undefined` ;
910915}
911916
912- function getCollectionFormat (
917+ function getCollectionFormatForParam (
913918 context : SdkContext ,
914919 param : SdkHttpParameter ,
915920 optionalParamName : string = "options"
916921) {
917922 const serializedName = getPropertySerializedName ( param ) ;
918923 const format = ( param as any ) . collectionFormat ;
919- const collectionInfo = getCollectionFormatHelper ( param . kind , format ?? "" ) ;
920- if ( ! collectionInfo ) {
921- throw "Has collection format info but without helper function detected" ;
922- }
923- const isMulti = format . toLowerCase ( ) === "multi" ;
924- const additionalParam = isMulti ? `, "${ serializedName } "` : "" ;
925- if ( ! param . optional ) {
926- return `"${ serializedName } ": ${ collectionInfo } (${ serializeRequestValue (
927- context ,
928- param . type ,
929- param . name ,
930- true ,
931- getEncodeForType ( param . type ) ,
932- true
933- ) } ${ additionalParam } )`;
934- }
935- return `"${ serializedName } ": ${ optionalParamName } ?.${
936- param . name
937- } !== undefined ? ${ collectionInfo } (${ serializeRequestValue (
924+ return `"${ serializedName } ": ${ serializeRequestValue (
938925 context ,
939926 param . type ,
940- `${ optionalParamName } ?.${ param . name } ` ,
941- false ,
942- getEncodeForType ( param . type ) ,
927+ param . optional ? `${ optionalParamName } ?.${ param . name } ` : param . name ,
928+ ! param . optional ,
929+ format ,
930+ serializedName ,
943931 true
944- ) } ${ additionalParam } ): undefined `;
932+ ) } `;
945933}
946934
947935function isContentType ( param : SdkHttpParameter ) : boolean {
@@ -992,6 +980,7 @@ function getRequired(context: SdkContext, param: SdkHttpParameter) {
992980 clientValue ,
993981 true ,
994982 getEncodeForType ( param . type ) ,
983+ serializedName ,
995984 true
996985 ) } `;
997986}
@@ -1033,6 +1022,7 @@ function getOptional(
10331022 paramName ,
10341023 false ,
10351024 getEncodeForType ( param . type ) ,
1025+ serializedName ,
10361026 true
10371027 ) } `;
10381028}
@@ -1172,6 +1162,41 @@ function getNullableCheck(name: string, type: SdkType) {
11721162 return `${ name } === null ? null :` ;
11731163}
11741164
1165+ /**
1166+ * Determines the appropriate encoding format for a model property, especially for arrays with collection format encoding.
1167+ * For example, returns "csv" for comma-delimited arrays or the property's type encoding for regular properties.
1168+ */
1169+ function getEncodeForModelProperty (
1170+ context : SdkContext ,
1171+ property : SdkModelPropertyType
1172+ ) : string | undefined {
1173+ if ( property . encode && property . type . kind === "array" ) {
1174+ // Only arrays of string type can have collectionFormat encoding
1175+ if ( property . type . valueType . kind !== "string" ) {
1176+ reportDiagnostic ( context . program , {
1177+ code : "un-supported-array-encoding" ,
1178+ format : {
1179+ arrayName : property . name ,
1180+ arrayType : property . type . valueType . kind
1181+ } ,
1182+ target : NoTarget
1183+ } ) ;
1184+ return getEncodeForType ( property . type ) ;
1185+ }
1186+
1187+ const collectionFormat = getCollectionFormatFromArrayEncoding (
1188+ property . encode
1189+ ) ;
1190+ if (
1191+ collectionFormat &&
1192+ hasCollectionFormatInfo ( property . kind , collectionFormat )
1193+ ) {
1194+ return collectionFormat ;
1195+ }
1196+ }
1197+ return getEncodeForType ( property . type ) ;
1198+ }
1199+
11751200function getSerializationExpressionForFlatten (
11761201 context : SdkContext ,
11771202 property : SdkModelPropertyType ,
@@ -1245,7 +1270,8 @@ export function getSerializationExpression(
12451270 property . type ,
12461271 propertyFullName ,
12471272 ! property . optional ,
1248- getEncodeForType ( property . type ) ,
1273+ getEncodeForModelProperty ( context , property ) ,
1274+ getPropertySerializedName ( property ) ,
12491275 propertyPath === "" ? true : false
12501276 ) ;
12511277 }
@@ -1373,27 +1399,25 @@ export function getResponseMapping(
13731399 context ,
13741400 property . type ,
13751401 `${ propertyPath } ${ dot } ["${ serializedName } "]` ,
1376- getEncodeForType ( property . type )
1377- ) ;
1378- props . push (
1379- `${ propertyName } : ${ deserializeValue === `${ propertyPath } ${ dot } ["${ serializedName } "]` ? "" : nullOrUndefinedPrefix } ${ deserializeValue } `
1402+ ! property . optional ,
1403+ getEncodeForModelProperty ( context , property )
13801404 ) ;
1405+ props . push ( `${ propertyName } : ${ deserializeValue } ` ) ;
13811406 }
13821407 }
13831408 return props ;
13841409}
13851410
13861411/**
1387- * This function helps converting strings into JS complex types recursively.
1388- * We need to drill down into Array elements to make sure that the element type is
1389- * deserialized correctly
1412+ * Converts JavaScript values to their serialized wire format for HTTP requests.
13901413 */
13911414export function serializeRequestValue (
13921415 context : SdkContext ,
13931416 type : SdkType ,
13941417 clientValue : string ,
13951418 required : boolean ,
13961419 format ?: string ,
1420+ serializedName ?: string ,
13971421 isTopLevel : boolean = false
13981422) : string {
13991423 const getSdkType = useSdkTypes ( ) ;
@@ -1414,8 +1438,8 @@ export function serializeRequestValue(
14141438 return `${ nullOrUndefinedPrefix } ${ clientValue } .toISOString()` ;
14151439 }
14161440 case "array" : {
1417- const prefix = nullOrUndefinedPrefix + clientValue ;
14181441 if ( type . valueType ) {
1442+ const prefix = nullOrUndefinedPrefix + clientValue ;
14191443 const elementNullOrUndefinedPrefix =
14201444 isTypeNullable ( type . valueType ) || getOptionalForType ( type . valueType )
14211445 ? "!p ? p : "
@@ -1435,7 +1459,17 @@ export function serializeRequestValue(
14351459 ) {
14361460 return `${ prefix } .map((p: any) => { return ${ elementNullOrUndefinedPrefix } p})` ;
14371461 } else {
1438- return `${ prefix } .map((p: any) => { return ${ elementNullOrUndefinedPrefix } ${ serializeRequestValue ( context , type . valueType , "p" , true , getEncodeForType ( type . valueType ) ) } })` ;
1462+ const serializedValue = `${ clientValue } .map((p: any) => { return ${ elementNullOrUndefinedPrefix } ${ serializeRequestValue ( context , type . valueType , "p" , true , getEncodeForType ( type . valueType ) ) } })` ;
1463+ if ( format ) {
1464+ const formatHelper = getCollectionFormatHelper ( format ) ;
1465+ if ( formatHelper ) {
1466+ if ( format ?. toLowerCase ( ) === KnownCollectionFormat . Multi ) {
1467+ return `${ nullOrUndefinedPrefix } ${ formatHelper } (${ serializedValue } , "${ serializedName } ")` ;
1468+ }
1469+ return `${ nullOrUndefinedPrefix } ${ formatHelper } (${ serializedValue } )` ;
1470+ }
1471+ }
1472+ return `${ nullOrUndefinedPrefix } ${ serializedValue } ` ;
14391473 }
14401474 }
14411475 return clientValue ;
@@ -1507,14 +1541,15 @@ export function deserializeResponseValue(
15071541 context : SdkContext ,
15081542 type : SdkType ,
15091543 restValue : string ,
1544+ required : boolean ,
15101545 format ?: string
15111546) : string {
15121547 const dependencies = useDependencies ( ) ;
15131548 const stringToUint8ArrayReference = resolveReference (
15141549 dependencies . stringToUint8Array
15151550 ) ;
15161551 const nullOrUndefinedPrefix =
1517- isTypeNullable ( type ) || getOptionalForType ( type )
1552+ isTypeNullable ( type ) || getOptionalForType ( type ) || ! required
15181553 ? `!${ restValue } ? ${ restValue } : `
15191554 : "" ;
15201555 switch ( type . kind ) {
@@ -1547,13 +1582,23 @@ export function deserializeResponseValue(
15471582 ) {
15481583 return `${ prefix } .map((p: any) => { return ${ elementNullOrUndefinedPrefix } p})` ;
15491584 } else if ( type . valueType ) {
1550- return `${ prefix } .map((p: any) => { return ${ elementNullOrUndefinedPrefix } ${ deserializeResponseValue ( context , type . valueType , "p" , getEncodeForType ( type . valueType ) ) } })` ;
1585+ if ( format ) {
1586+ const parseHelper = getCollectionFormatParseHelper ( format ) ;
1587+ if ( parseHelper ) {
1588+ // We shouldn't check for an empty string here since an empty string should be parsed as an empty array
1589+ const optionalPrefixForString =
1590+ isTypeNullable ( type ) || getOptionalForType ( type ) || ! required
1591+ ? `${ restValue } === null || ${ restValue } === undefined ? ${ restValue } : `
1592+ : "" ;
1593+ return `${ optionalPrefixForString } ${ parseHelper } (${ restValue } )` ;
1594+ }
1595+ }
1596+ return `${ prefix } .map((p: any) => { return ${ elementNullOrUndefinedPrefix } ${ deserializeResponseValue ( context , type . valueType , "p" , true , getEncodeForType ( type . valueType ) ) } })` ;
15511597 } else {
15521598 return restValue ;
15531599 }
15541600 }
15551601 case "dict" : {
1556- const prefix = nullOrUndefinedPrefix + restValue ;
15571602 let elementNullOrUndefinedPrefix = "" ;
15581603 if (
15591604 type . valueType &&
@@ -1572,21 +1617,21 @@ export function deserializeResponseValue(
15721617 )
15731618 : undefined ;
15741619 if ( deserializeFunctionName ) {
1575- return `Object.fromEntries(Object.entries(${ prefix } ).map(([k, p]: [string, any]) => [k, ${ elementNullOrUndefinedPrefix } ${ deserializeFunctionName } (p)]))` ;
1620+ return `${ nullOrUndefinedPrefix } Object.fromEntries(Object.entries(${ restValue } ).map(([k, p]: [string, any]) => [k, ${ elementNullOrUndefinedPrefix } ${ deserializeFunctionName } (p)]))` ;
15761621 } else if (
15771622 type . valueType &&
15781623 isAzureCoreErrorType ( context . program , type . valueType . __raw )
15791624 ) {
1580- return `Object.fromEntries(Object.entries(${ prefix } ).map(([k, p]: [string, any]) => [k, ${ elementNullOrUndefinedPrefix } p]))` ;
1625+ return `${ nullOrUndefinedPrefix } Object.fromEntries(Object.entries(${ restValue } ).map(([k, p]: [string, any]) => [k, ${ elementNullOrUndefinedPrefix } p]))` ;
15811626 } else if ( type . valueType ) {
1582- return `Object.fromEntries(Object.entries(${ prefix } ).map(([k, p]: [string, any]) => [k, ${ elementNullOrUndefinedPrefix } ${ deserializeResponseValue ( context , type . valueType , "p" , getEncodeForType ( type . valueType ) ) } ]))` ;
1627+ return `${ nullOrUndefinedPrefix } Object.fromEntries(Object.entries(${ restValue } ).map(([k, p]: [string, any]) => [k, ${ elementNullOrUndefinedPrefix } ${ deserializeResponseValue ( context , type . valueType , "p" , true , getEncodeForType ( type . valueType ) ) } ]))` ;
15831628 } else {
15841629 return restValue ;
15851630 }
15861631 }
15871632 case "bytes" :
15881633 if ( format !== "binary" && format !== "bytes" ) {
1589- return `typeof ${ restValue } === 'string'
1634+ return `${ nullOrUndefinedPrefix } typeof ${ restValue } === 'string'
15901635 ? ${ stringToUint8ArrayReference } (${ restValue } , "${ format ?? "base64" } ")
15911636 : ${ restValue } ` ;
15921637 }
@@ -1616,6 +1661,7 @@ export function deserializeResponseValue(
16161661 context ,
16171662 type . type ,
16181663 restValue ,
1664+ false ,
16191665 getEncodeForType ( type . type )
16201666 ) ;
16211667 default :
0 commit comments