@rxap/xml-parser
Version:
Provides a set of decorators and services for parsing and serializing XML documents into TypeScript classes. It simplifies the process of mapping XML elements and attributes to class properties, handling data validation, and serializing objects back into
130 lines • 7.23 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ElementChildRawContentSerializer = exports.ElementChildRawContentParser = void 0;
exports.AssertElementChildRawContentOptions = AssertElementChildRawContentOptions;
exports.ElementChildRawContent = ElementChildRawContent;
const tslib_1 = require("tslib");
const mixin_1 = require("@rxap/mixin");
const reflect_metadata_1 = require("@rxap/reflect-metadata");
const utilities_1 = require("@rxap/utilities");
const error_1 = require("../error");
const metadata_keys_1 = require("./metadata-keys");
const tag_element_mixin_1 = require("./mixins/tag-element.mixin");
const text_content_element_mixin_1 = require("./mixins/text-content-element.mixin");
const required_property_1 = require("./required-property");
const utilities_2 = require("./utilities");
/**
* Asserts that the provided `options` object is an instance of `ElementChildRawContentOptions`.
* This function performs a runtime check to ensure that the `options` object conforms to the expected structure
* of `ElementChildRawContentOptions`. Specifically, it checks if the `options` object has a "tag" property,
* which is essential for identifying it as a valid `ElementChildRawContentOptions` instance.
*
* @param options - The object to be validated as an instance of `ElementChildRawContentOptions`.
* @throws {Error} Throws an error if the `options` object does not have a "tag" property, indicating
* that it is not a valid `ElementChildRawContentOptions`.
* @template T - The type parameter that specifies the type of the content within the `ElementChildRawContentOptions`.
*/
function AssertElementChildRawContentOptions(options) {
if (!(0, tag_element_mixin_1.IsTagElementOptions)(options)) {
throw new Error('The object is not a ElementChildRawContentOptions. The required property "tag" is missing!');
}
}
let ElementChildRawContentParser = class ElementChildRawContentParser {
constructor(propertyKey, options) {
this.propertyKey = propertyKey;
this.options = options;
this.parse = this.parse.bind(this);
Reflect.set(this.parse, 'propertyKey', propertyKey);
}
parse(xmlParser, element, parsedElement) {
if (element.hasChild(this.tag)) {
const rawValue = element.getChildRawContent(this.tag, this.defaultValue);
if (rawValue !== undefined) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
parsedElement[this.propertyKey] = this.parseValue(rawValue);
}
}
else if (this.required) {
throw new error_1.RxapXmlParserValidateRequiredError(`Element <${element.name}> child <${this.tag}> raw content is required!`, parsedElement.__tag);
}
return parsedElement;
}
};
exports.ElementChildRawContentParser = ElementChildRawContentParser;
exports.ElementChildRawContentParser = ElementChildRawContentParser = tslib_1.__decorate([
(0, mixin_1.Mixin)(text_content_element_mixin_1.TextContentElementMixin, tag_element_mixin_1.TagElementMixin),
tslib_1.__metadata("design:paramtypes", [String, Object])
], ElementChildRawContentParser);
let ElementChildRawContentSerializer = class ElementChildRawContentSerializer {
constructor(propertyKey, options) {
this.propertyKey = propertyKey;
this.options = options;
this.serialize = this.serialize.bind(this);
Reflect.set(this.serialize, 'propertyKey', propertyKey);
}
serialize(xmlParser, element, parsedElement) {
// @ts-expect-error the propertyKey is set by the property decorator
const child = parsedElement[this.propertyKey];
if (child) {
element.setChildRawContent(this.tag, this.serializeValue(child));
}
else if (this.required) {
throw new error_1.RxapXmlParserValidateRequiredError(`Element <${element.name}> child <${this.tag}> raw content is required!`, parsedElement.__tag);
}
}
};
exports.ElementChildRawContentSerializer = ElementChildRawContentSerializer;
exports.ElementChildRawContentSerializer = ElementChildRawContentSerializer = tslib_1.__decorate([
(0, mixin_1.Mixin)(text_content_element_mixin_1.TextContentElementMixin, tag_element_mixin_1.TagElementMixin),
tslib_1.__metadata("design:paramtypes", [String, Object])
], ElementChildRawContentSerializer);
/**
* Decorator factory that creates a decorator to parse and inject raw content from a child element into a class property.
*
* This decorator can be applied to properties within classes that are meant to interact with DOM-like structures, where
* the content of a specified child element is directly assigned to the property. The child element is identified by a tag,
* which can be customized through the options provided.
*
* @param {Partial<ElementChildRawContentParserOptions<Value>> | string} optionsOrString - This parameter can either be a string
* representing the tag of the child element or an object containing various configuration options. If a string is provided,
* it is used as the tag name of the child element. If an object is provided, it can specify detailed options such as the tag name,
* whether the child element is required, and other parser-specific options.
*
* @returns {Function} A class decorator function that takes two parameters: `target`, the constructor of the class, and
* `propertyKey`, the name of the property to which the decorator is applied. This decorator function initializes and configures
* an instance of `ElementChildRawContentParser` based on the provided options and attaches it to the metadata of the target class.
*
* ### Usage
*
* ```typescript
* class MyComponent {
* @ElementChildRawContent({ tag: 'my-child', required: true })
* content: string;
* }
* ```
*
* In the above example, the `ElementChildRawContent` decorator is used to specify that the `content` property of `MyComponent`
* should be filled with the raw content of a child element `<my-child>` which is required to be present.
*
*/
function ElementChildRawContent(optionsOrString) {
return function (target, propertyKey) {
let options = optionsOrString === undefined ?
{ tag: (0, utilities_1.dasherize)(propertyKey) } :
typeof optionsOrString === 'string' ? { tag: optionsOrString } : optionsOrString;
options = (0, utilities_1.deepMerge)(options, (0, reflect_metadata_1.getMetadata)(metadata_keys_1.ElementParserMetaData.OPTIONS, target, propertyKey) || {});
if (!options.tag) {
options.tag = (0, utilities_1.dasherize)(propertyKey);
}
AssertElementChildRawContentOptions(options);
const parser = new ElementChildRawContentParser(propertyKey, options);
(0, utilities_2.AddParserToMetadata)(parser, target);
const serializer = new ElementChildRawContentSerializer(propertyKey, options);
(0, utilities_2.AddSerializerToMetadata)(serializer, target);
if (options.required) {
(0, required_property_1.RequiredProperty)()(target, propertyKey);
}
};
}
//# sourceMappingURL=element-child-raw-content.js.map