function serializeCompositeType()

in sdk/core/core-client/src/serializer.ts [708:821]


function serializeCompositeType(
  serializer: Serializer,
  mapper: CompositeMapper,
  object: any,
  objectName: string,
  isXml: boolean,
  options: RequiredSerializerOptions,
): any {
  if (getPolymorphicDiscriminatorRecursively(serializer, mapper)) {
    mapper = getPolymorphicMapper(serializer, mapper, object, "clientName");
  }

  if (object !== undefined && object !== null) {
    const payload: any = {};
    const modelProps = resolveModelProperties(serializer, mapper, objectName);
    for (const key of Object.keys(modelProps)) {
      const propertyMapper = modelProps[key];
      if (propertyMapper.readOnly) {
        continue;
      }

      let propName: string | undefined;
      let parentObject: any = payload;
      if (serializer.isXML) {
        if (propertyMapper.xmlIsWrapped) {
          propName = propertyMapper.xmlName;
        } else {
          propName = propertyMapper.xmlElementName || propertyMapper.xmlName;
        }
      } else {
        const paths = splitSerializeName(propertyMapper.serializedName!);
        propName = paths.pop();

        for (const pathName of paths) {
          const childObject = parentObject[pathName];
          if (
            (childObject === undefined || childObject === null) &&
            ((object[key] !== undefined && object[key] !== null) ||
              propertyMapper.defaultValue !== undefined)
          ) {
            parentObject[pathName] = {};
          }
          parentObject = parentObject[pathName];
        }
      }

      if (parentObject !== undefined && parentObject !== null) {
        if (isXml && mapper.xmlNamespace) {
          const xmlnsKey = mapper.xmlNamespacePrefix
            ? `xmlns:${mapper.xmlNamespacePrefix}`
            : "xmlns";
          parentObject[XML_ATTRKEY] = {
            ...parentObject[XML_ATTRKEY],
            [xmlnsKey]: mapper.xmlNamespace,
          };
        }
        const propertyObjectName =
          propertyMapper.serializedName !== ""
            ? objectName + "." + propertyMapper.serializedName
            : objectName;

        let toSerialize = object[key];
        const polymorphicDiscriminator = getPolymorphicDiscriminatorRecursively(serializer, mapper);
        if (
          polymorphicDiscriminator &&
          polymorphicDiscriminator.clientName === key &&
          (toSerialize === undefined || toSerialize === null)
        ) {
          toSerialize = mapper.serializedName;
        }

        const serializedValue = serializer.serialize(
          propertyMapper,
          toSerialize,
          propertyObjectName,
          options,
        );
        if (serializedValue !== undefined && propName !== undefined && propName !== null) {
          const value = getXmlObjectValue(propertyMapper, serializedValue, isXml, options);
          if (isXml && propertyMapper.xmlIsAttribute) {
            // XML_ATTRKEY, i.e., $ is the key attributes are kept under in xml2js.
            // This keeps things simple while preventing name collision
            // with names in user documents.
            parentObject[XML_ATTRKEY] = parentObject[XML_ATTRKEY] || {};
            parentObject[XML_ATTRKEY][propName] = serializedValue;
          } else if (isXml && propertyMapper.xmlIsWrapped) {
            parentObject[propName] = { [propertyMapper.xmlElementName!]: value };
          } else {
            parentObject[propName] = value;
          }
        }
      }
    }

    const additionalPropertiesMapper = resolveAdditionalProperties(serializer, mapper, objectName);
    if (additionalPropertiesMapper) {
      const propNames = Object.keys(modelProps);
      for (const clientPropName in object) {
        const isAdditionalProperty = propNames.every((pn) => pn !== clientPropName);
        if (isAdditionalProperty) {
          payload[clientPropName] = serializer.serialize(
            additionalPropertiesMapper,
            object[clientPropName],
            objectName + '["' + clientPropName + '"]',
            options,
          );
        }
      }
    }

    return payload;
  }
  return object;
}