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
TypeScript
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;
};
}