UNPKG

xml-class-transformer

Version:

Fluently parse XML into beautiful JS/TS classes and serialize them. GoLang's encoding/xml alternative for JS/TS world.

219 lines (218 loc) 7.31 kB
import type * as xmljs from 'xml-js-v2'; import { Marshaller } from './marshallers'; /** * Only here for the sake of the documentation and type checking. * No need to "implement" this interface. * * The XML class's constructor should not require any arguments. * This is because the xml-class-transformer needs to be able to construct them * when it needs to. And if the constructor relies on the arguments then it will crash. * * Note that it is okay and even recommended to give your classes a constructor like this: * ```ts * class SomeXmlElement { * ... * constructor(seed?: SomeXmlElement) { * Object.assign(this, seed || {}) * } * } * ``` * * note that the `seed` argument is optional. Such a constructor * gives you a way to create instances with passed values and also * enable the library to construct them without passing any arguments. */ export type XmlClass = { new (): any; }; /** * These types are considered as primitive, * which means that there are built-in marshallers for them, * and you can simply do `{ type: () => String }`. */ export type XmlPrimitiveType = typeof String | typeof Number | typeof Boolean | typeof BigInt | typeof Date; export type XmlType = XmlPrimitiveType | XmlClass; export interface XmlElemOptions { /** * The xmlns attribute value. Specifies the default XML namespace. * This is just a shortcut for the `@XmlAttribute({ name: 'xmlns', type: () => String })` property decorator. * * @example * { xmlns: 'http://s3.amazonaws.com/doc/2006-03-01/' } */ xmlns?: string; /** * XML element name. * If not specified, the class name will be used. */ name?: string; } export interface XmlChildElemOptions { /** * Specify primitive type or class type for parsing and serializing. * * Not compatible with the `union` and `marshaller` options. * * @example * { type: () => String } * { type: () => Number } * { type: () => Boolean } * { type: () => BigInt } * { type: () => Date } * { type: () => CustomClass } */ type?: () => XmlType; /** * A custom marshaller. * Not compatible with the `type` and `union` options. * * @example * class CapitalizedBooleanMarshaller implements Marshaller<boolean> { * marshal(obj: boolean): string { * return obj ? 'True' : 'False'; * } * * unmarshal(chardata: string | undefined): boolean { * return chardata == 'True' ? true : false; * } * } * \@XmlChildElem({ marshaller: new CapitalizedBooleanMarshaller() }) * isSomethingEnabled: boolean; * * @example * const momentMarshaller: Marshaller<moment.Moment> = { * marshal = (val: moment.Moment): string => val.toISOString(), * unmarshal = (chardata: string): moment.Moment => moment(chardata) , * } * \@XmlChildElem({ marshaller: momentMarshaller }) * creationDateOfSomething: moment.Moment; */ marshaller?: Marshaller<unknown>; /** * You can also specify union types, then at the parsing time * the one whose name matches the XML element name will be selected. * The serialization of union types is performed in the same manner: * the name of the class is used as the XML element name. * * Union types are not compatible with the `type`, `marshaller` and `name` options. * * Primitive types are not supported in unions. * * @example * { union: () => [User, Admin] } */ union?: () => XmlClass[]; /** * If true, the property will be parsed and serialized as an array. */ array?: boolean; /** * A custom XML element name. * If not specified, the property name will be used. * It is recommended to specify it explicitly for expressiveness. * * Not compatible with the `union` option, because union typed elements name is * gathered from the union's members names. */ name?: string | undefined; } export interface XmlAttributeOptions { /** * XML attribute name. * If not specified, the property name will be used. */ name?: string | undefined; /** * XML Attributes can only be of primitive types. * Specify the primitive type for parsing and serializing the attribute. * * Not compatible with the `marshaller` options. * * @example * { type: () => String } * { type: () => Number } * { type: () => Boolean } * { type: () => BigInt } * { type: () => Date } * { type: () => CustomClass } */ type?: () => XmlPrimitiveType; /** * A custom marshaller. * Not compatible with the `type` options. * * @example * class CapitalizedBooleanMarshaller implements Marshaller<boolean> { * marshal(obj: boolean): string { * return obj ? 'True' : 'False'; * } * * unmarshal(chardata: string | undefined): boolean { * return chardata == 'True' ? true : false; * } * } * \@XmlAttribute({ marshaller: new CapitalizedBooleanMarshaller() }) * isSomethingEnabled: boolean; * * @example * const momentMarshaller: Marshaller<moment.Moment> = { * marshal = (val: moment.Moment): string => val.toISOString(), * unmarshal = (chardata: string): moment.Moment => moment(chardata) , * } * \@XmlAttribute({ marshaller: momentMarshaller }) * creationDateOfSomething: moment.Moment; */ marshaller?: Marshaller<unknown>; } export interface XmlChardataOptions { /** * An XML chardata an only be of primitive types. * Specify the primitive type for parsing and serializing the chardata. * * Not compatible with the `marshaller` options. * * @example * { type: () => String } * { type: () => Number } * { type: () => Boolean } * { type: () => BigInt } * { type: () => Date } * { type: () => CustomClass } */ type?: () => XmlPrimitiveType; /** * A custom marshaller. * Not compatible with the `type` options. * * @example * class CapitalizedBooleanMarshaller implements Marshaller<boolean> { * marshal(obj: boolean): string { * return obj ? 'True' : 'False'; * } * * unmarshal(chardata: string | undefined): boolean { * return chardata == 'True' ? true : false; * } * } * \@XmlChardata({ marshaller: new CapitalizedBooleanMarshaller() }) * isSomethingEnabled: boolean; * * @example * const momentMarshaller: Marshaller<moment.Moment> = { * marshal = (val: moment.Moment): string => val.toISOString(), * unmarshal = (chardata: string): moment.Moment => moment(chardata) , * } * \@XmlChardata({ marshaller: momentMarshaller }) * creationDateOfSomething: moment.Moment; */ marshaller?: Marshaller<unknown>; } export interface ClassToXmlOptions extends xmljs.Options.JS2XML { /** * Whether to include the default declaration line `<?xml version="1.0" encoding="UTF-8"?>` or not. * @default true */ declaration?: boolean | { attributes?: xmljs.DeclarationAttributes; }; }