xml-model 1.3.1 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/_virtual/_commonjsHelpers.js +4 -10
  2. package/dist/defaults.d.ts +13 -0
  3. package/dist/defaults.js +45 -9
  4. package/dist/errors.d.ts +16 -0
  5. package/dist/errors.js +14 -20
  6. package/dist/middleware.js +4 -10
  7. package/dist/model/built-ins.js +0 -3
  8. package/dist/model/index.d.ts +48 -0
  9. package/dist/model/index.js +58 -38
  10. package/dist/model/property.d.ts +12 -0
  11. package/dist/model/property.js +9 -13
  12. package/dist/model/registry.js +2 -9
  13. package/dist/model/types.d.ts +35 -0
  14. package/dist/node_modules/reflect-metadata/Reflect.js +9 -70
  15. package/dist/types.d.ts +8 -0
  16. package/dist/util/is-regexp.js +0 -3
  17. package/dist/util/kebab-case.js +0 -3
  18. package/dist/util/merge-maps.js +1 -5
  19. package/dist/vite/index.d.ts +80 -0
  20. package/{vite/dist → dist/vite}/index.js +9 -1
  21. package/dist/xml/index.d.ts +47 -0
  22. package/dist/xml/index.js +8 -24
  23. package/package.json +11 -9
  24. package/dist/model/types.js +0 -2
  25. package/dist/types.js +0 -2
  26. package/vite/dist/src/class-names.test.d.ts +0 -9
  27. package/vite/dist/src/defaults.d.ts +0 -15
  28. package/vite/dist/src/errors.d.ts +0 -24
  29. package/vite/dist/src/index.d.ts +0 -8
  30. package/vite/dist/src/middleware.d.ts +0 -10
  31. package/vite/dist/src/model/built-ins.d.ts +0 -3
  32. package/vite/dist/src/model/index.d.ts +0 -21
  33. package/vite/dist/src/model/property.d.ts +0 -6
  34. package/vite/dist/src/model/registry.d.ts +0 -9
  35. package/vite/dist/src/model/types.d.ts +0 -74
  36. package/vite/dist/src/model.test.d.ts +0 -2
  37. package/vite/dist/src/types.d.ts +0 -17
  38. package/vite/dist/src/util/is-regexp.d.ts +0 -12
  39. package/vite/dist/src/util/kebab-case.d.ts +0 -16
  40. package/vite/dist/src/util/merge-maps.d.ts +0 -2
  41. package/vite/dist/src/xml/index.d.ts +0 -33
  42. package/vite/dist/src/xml/xml-js.d.ts +0 -7
  43. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/common/format.js +0 -0
  44. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/common/index.js +0 -0
  45. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/api-call-transformer.js +0 -0
  46. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/common/class-analyzer.js +0 -0
  47. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/common/compile-error.js +0 -0
  48. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/common/import-analyzer.js +0 -0
  49. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/common/interface-analyzer.js +0 -0
  50. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/common/visitor-base.js +0 -0
  51. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/declarations-emitter.js +0 -0
  52. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/encode-parameter.js +0 -0
  53. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/find-relative-path.js +0 -0
  54. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/flags.js +0 -0
  55. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/forward-ref.js +0 -0
  56. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/get-exports-for-symbol.js +0 -0
  57. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/index.js +0 -0
  58. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/legacy-decorator.js +0 -0
  59. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/legacy-type-encoder.js +0 -0
  60. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/literal-node.js +0 -0
  61. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/metadata-collector.js +0 -0
  62. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/metadata-decorator.js +0 -0
  63. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/metadata-emitter.js +0 -0
  64. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/metadata-encoder.js +0 -0
  65. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/rt-helper.js +0 -0
  66. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/rtti-visitor-base.js +0 -0
  67. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/serialize.js +0 -0
  68. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/type-encoder.js +0 -0
  69. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/type-literal.js +0 -0
  70. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/utils.js +0 -0
  71. /package/{vite/dist → dist/vite}/node_modules/typescript-rtti/dist.esm/transformer/workarounds.js +0 -0
@@ -1,23 +1,18 @@
1
- var __defProp = Object.defineProperty;
2
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
1
  var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
4
2
  function getDefaultExportFromCjs(x) {
5
3
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
6
4
  }
7
- __name(getDefaultExportFromCjs, "getDefaultExportFromCjs");
8
5
  function getDefaultExportFromNamespaceIfPresent(n) {
9
6
  return n && Object.prototype.hasOwnProperty.call(n, "default") ? n["default"] : n;
10
7
  }
11
- __name(getDefaultExportFromNamespaceIfPresent, "getDefaultExportFromNamespaceIfPresent");
12
8
  function getDefaultExportFromNamespaceIfNotNamed(n) {
13
9
  return n && Object.prototype.hasOwnProperty.call(n, "default") && Object.keys(n).length === 1 ? n["default"] : n;
14
10
  }
15
- __name(getDefaultExportFromNamespaceIfNotNamed, "getDefaultExportFromNamespaceIfNotNamed");
16
11
  function getAugmentedNamespace(n) {
17
12
  if (Object.prototype.hasOwnProperty.call(n, "__esModule")) return n;
18
13
  var f = n.default;
19
14
  if (typeof f == "function") {
20
- var a = /* @__PURE__ */ __name(function a2() {
15
+ var a = function a2() {
21
16
  var isInstance = false;
22
17
  try {
23
18
  isInstance = this instanceof a2;
@@ -27,7 +22,7 @@ function getAugmentedNamespace(n) {
27
22
  return Reflect.construct(f, arguments, this.constructor);
28
23
  }
29
24
  return f.apply(this, arguments);
30
- }, "a");
25
+ };
31
26
  a.prototype = f.prototype;
32
27
  } else a = {};
33
28
  Object.defineProperty(a, "__esModule", { value: true });
@@ -35,14 +30,13 @@ function getAugmentedNamespace(n) {
35
30
  var d = Object.getOwnPropertyDescriptor(n, k);
36
31
  Object.defineProperty(a, k, d.get ? d : {
37
32
  enumerable: true,
38
- get: /* @__PURE__ */ __name(function() {
33
+ get: function() {
39
34
  return n[k];
40
- }, "get")
35
+ }
41
36
  });
42
37
  });
43
38
  return a;
44
39
  }
45
- __name(getAugmentedNamespace, "getAugmentedNamespace");
46
40
  export {
47
41
  commonjsGlobal,
48
42
  getAugmentedNamespace,
@@ -10,6 +10,19 @@ interface Defaults {
10
10
  tagnameFromProperty<T>(property: XMLModelPropertyOptions<T>): string;
11
11
  propertyToXML<T>(context: PropertyToXMLContext<T>): XMLRoot;
12
12
  }
13
+ /**
14
+ * Global defaults used by all models and properties when no override is provided.
15
+ *
16
+ * You can mutate individual entries to change library-wide behaviour — for example,
17
+ * replace `defaults.fromXML` to provide a base deserialization strategy instead of
18
+ * having to specify `fromXML` on every `@Model()`.
19
+ *
20
+ * Key behaviours:
21
+ * - `fromXML` — throws by default; every root model **must** provide its own implementation.
22
+ * - `tagnameFromModel` / `tagnameFromProperty` — convert class/property names to kebab-case.
23
+ * - `propertyFromXML` — handles class, array, and union-of-literal property types via runtime reflection.
24
+ * - `propertyToXML` — serialises class, array, and union-of-literal values; respects `inline`.
25
+ */
13
26
  export declare const defaults: Defaults;
14
27
  export {};
15
28
  //# sourceMappingURL=defaults.d.ts.map
package/dist/defaults.js CHANGED
@@ -1,18 +1,36 @@
1
- var __defProp = Object.defineProperty;
2
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
1
  import { getModel } from "./model/registry.js";
4
2
  import { kebabCase } from "./util/kebab-case.js";
5
3
  const defaults = {
4
+ /**
5
+ * Default model-level `fromXML` handler.
6
+ * Always throws — models must supply their own `fromXML` or inherit one from a parent.
7
+ * @throws {TypeError}
8
+ */
6
9
  fromXML() {
7
- throw new TypeError("you should define 'defaults.fromXML' yourself or provide a 'fromXML' function to @Model() decorator's options");
10
+ throw new TypeError(
11
+ "you should define 'defaults.fromXML' yourself or provide a 'fromXML' function to @Model() decorator's options"
12
+ );
8
13
  },
14
+ /**
15
+ * Collects the XML elements that are the source data for a property.
16
+ * Assumes `xml.elements[0]` is the wrapper element that contains all property tags.
17
+ */
9
18
  propertyResolveSourceElements(context) {
10
19
  const innerElements = context.xml.elements[0]?.elements || [];
11
20
  return innerElements.filter((el) => context.property.isSourceElement(el, context));
12
21
  },
22
+ /**
23
+ * Returns `true` when the element's tag name matches the property's tagname.
24
+ */
13
25
  propertySourceElementsFilter(element, context) {
14
26
  return context.property.tagname === element.name;
15
27
  },
28
+ /**
29
+ * Converts resolved XML elements into a typed property value.
30
+ * Handles class types, arrays of class types, and union-of-literal types.
31
+ * Returns `undefined` for optional properties with no matching elements,
32
+ * and also for unrecognised types.
33
+ */
16
34
  propertyFromXML(context) {
17
35
  const prop = context.property;
18
36
  const elements = context.elements;
@@ -54,7 +72,11 @@ const defaults = {
54
72
  }
55
73
  return void 0;
56
74
  },
57
- /* Object -> XML */
75
+ /**
76
+ * Default model-level `toXML` handler.
77
+ * Collects serialised property fragments and wraps them in a root element
78
+ * named after the model's tagname.
79
+ */
58
80
  toXML({ properties, model }) {
59
81
  const elements = [];
60
82
  model.resolveAllProperties().forEach((prop) => {
@@ -76,12 +98,25 @@ const defaults = {
76
98
  ]
77
99
  };
78
100
  },
101
+ /**
102
+ * Derives the XML tag name for a model from its class name, converted to kebab-case.
103
+ * e.g. `MyClass` → `my-class`.
104
+ */
79
105
  tagnameFromModel(model) {
80
106
  return kebabCase(model.type.name);
81
107
  },
108
+ /**
109
+ * Derives the XML tag name for a property from its name, converted to kebab-case.
110
+ * e.g. `myProp` → `my-prop`.
111
+ */
82
112
  tagnameFromProperty(property) {
83
113
  return kebabCase(String(property.name));
84
114
  },
115
+ /**
116
+ * Converts a typed property value to an `XMLRoot` fragment.
117
+ * Handles class types, arrays of class types, and union-of-literal types.
118
+ * When the property has `inline: true`, array items are flattened into the parent element.
119
+ */
85
120
  propertyToXML(context) {
86
121
  const property = context.property;
87
122
  const type = property.reflected.type;
@@ -92,7 +127,7 @@ const defaults = {
92
127
  if (property.model) {
93
128
  return property.model.toXML(value);
94
129
  }
95
- const getXML = /* @__PURE__ */ __name(() => {
130
+ const getXML = () => {
96
131
  if (type.is("class")) {
97
132
  const model = getModel(type.class);
98
133
  return model.toXML(value);
@@ -108,19 +143,20 @@ const defaults = {
108
143
  const firstType = type.types[0];
109
144
  if (firstType.is("literal")) {
110
145
  const firstTypeCtor = firstType.value.constructor;
111
- if (type.types.every((type2) => type2.is("literal") && type2.value.constructor === firstTypeCtor)) {
146
+ if (type.types.every(
147
+ (type2) => type2.is("literal") && type2.value.constructor === firstTypeCtor
148
+ )) {
112
149
  const model = getModel(firstTypeCtor);
113
150
  return model.toXML(context.value);
114
151
  }
115
152
  }
116
153
  }
117
154
  return { elements: [] };
118
- }, "getXML");
155
+ };
119
156
  const xml = getXML();
120
157
  if (context.property.inline)
121
158
  return { elements: xml.elements.map((el) => el.elements || []).flat() };
122
- else
123
- return xml;
159
+ else return xml;
124
160
  }
125
161
  };
126
162
  export {
package/dist/errors.d.ts CHANGED
@@ -1,21 +1,37 @@
1
1
  import { fromXMLContext, PropertyFromXMLContext, PropertyToXMLContext, toXMLContext } from './model/types';
2
+ /**
3
+ * Thrown when model-level XML → object conversion fails.
4
+ * Wraps the original error along with the conversion context.
5
+ */
2
6
  export declare class FromXMLConversionError<T> extends Error {
3
7
  context: Omit<fromXMLContext<T>, "properties">;
4
8
  error: unknown;
5
9
  name: string;
6
10
  constructor(context: Omit<fromXMLContext<T>, "properties">, error: unknown);
7
11
  }
12
+ /**
13
+ * Thrown when a single property's XML → value conversion fails.
14
+ * Extends `FromXMLConversionError` with additional property context.
15
+ */
8
16
  export declare class PropertyFromXMLConversionError<T> extends FromXMLConversionError<T> {
9
17
  propertyContext: PropertyFromXMLContext<T>;
10
18
  name: string;
11
19
  constructor(context: Omit<fromXMLContext<T>, "properties">, propertyContext: PropertyFromXMLContext<T>, error: unknown);
12
20
  }
21
+ /**
22
+ * Thrown when model-level object → XML conversion fails.
23
+ * Wraps the original cause along with the conversion context.
24
+ */
13
25
  export declare class ToXMLConversionError<T> extends Error {
14
26
  context: Omit<toXMLContext<T>, "properties">;
15
27
  cause: unknown;
16
28
  name: string;
17
29
  constructor(context: Omit<toXMLContext<T>, "properties">, cause: unknown);
18
30
  }
31
+ /**
32
+ * Thrown when a single property's value → XML conversion fails.
33
+ * Extends `ToXMLConversionError` with additional property context.
34
+ */
19
35
  export declare class PropertyToXMLConversionError<T> extends ToXMLConversionError<T> {
20
36
  propertyContext: PropertyToXMLContext<T>;
21
37
  name: string;
package/dist/errors.js CHANGED
@@ -1,6 +1,4 @@
1
- var __defProp = Object.defineProperty;
2
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
- const _FromXMLConversionError = class _FromXMLConversionError extends Error {
1
+ class FromXMLConversionError extends Error {
4
2
  constructor(context, error) {
5
3
  const message = `[Model: ${context.model.type.name}] failed to convert from XML`;
6
4
  super(message);
@@ -8,20 +6,18 @@ const _FromXMLConversionError = class _FromXMLConversionError extends Error {
8
6
  this.error = error;
9
7
  this.name = "FromXMLConversionError";
10
8
  }
11
- };
12
- __name(_FromXMLConversionError, "FromXMLConversionError");
13
- let FromXMLConversionError = _FromXMLConversionError;
14
- const _PropertyFromXMLConversionError = class _PropertyFromXMLConversionError extends FromXMLConversionError {
9
+ }
10
+ class PropertyFromXMLConversionError extends FromXMLConversionError {
15
11
  constructor(context, propertyContext, error) {
16
12
  super(context, error);
17
13
  this.propertyContext = propertyContext;
18
14
  this.name = "PropertyFromXMLConversionError";
19
- this.message = `[Model: ${context.model.type.name}] failed to convert prop <${String(propertyContext.property.name)}> from XML`;
15
+ this.message = `[Model: ${context.model.type.name}] failed to convert prop <${String(
16
+ propertyContext.property.name
17
+ )}> from XML`;
20
18
  }
21
- };
22
- __name(_PropertyFromXMLConversionError, "PropertyFromXMLConversionError");
23
- let PropertyFromXMLConversionError = _PropertyFromXMLConversionError;
24
- const _ToXMLConversionError = class _ToXMLConversionError extends Error {
19
+ }
20
+ class ToXMLConversionError extends Error {
25
21
  constructor(context, cause) {
26
22
  const message = `[Model: ${context.model.type.name}] failed to convert to XML`;
27
23
  super(message);
@@ -29,19 +25,17 @@ const _ToXMLConversionError = class _ToXMLConversionError extends Error {
29
25
  this.cause = cause;
30
26
  this.name = "ToXMLConversionError";
31
27
  }
32
- };
33
- __name(_ToXMLConversionError, "ToXMLConversionError");
34
- let ToXMLConversionError = _ToXMLConversionError;
35
- const _PropertyToXMLConversionError = class _PropertyToXMLConversionError extends ToXMLConversionError {
28
+ }
29
+ class PropertyToXMLConversionError extends ToXMLConversionError {
36
30
  constructor(context, propertyContext, cause) {
37
31
  super(context, cause);
38
32
  this.propertyContext = propertyContext;
39
33
  this.name = "PropertyToXMLConversionError";
40
- this.message = `[Model: ${context.model.type.name}] failed to convert prop <${String(propertyContext.property.name)}> to XML`;
34
+ this.message = `[Model: ${context.model.type.name}] failed to convert prop <${String(
35
+ propertyContext.property.name
36
+ )}> to XML`;
41
37
  }
42
- };
43
- __name(_PropertyToXMLConversionError, "PropertyToXMLConversionError");
44
- let PropertyToXMLConversionError = _PropertyToXMLConversionError;
38
+ }
45
39
  export {
46
40
  FromXMLConversionError,
47
41
  PropertyFromXMLConversionError,
@@ -1,29 +1,23 @@
1
- var __defProp = Object.defineProperty;
2
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
1
  function* MiddlewareChain(options) {
4
2
  do {
5
3
  for (let index = options.middlewares.length - 1; index >= 0; index--) {
6
4
  yield options.middlewares[index];
7
5
  }
8
- if (options.parent)
9
- options = options.parent;
10
- else
11
- return;
6
+ if (options.parent) options = options.parent;
7
+ else return;
12
8
  } while (true);
13
9
  }
14
- __name(MiddlewareChain, "MiddlewareChain");
15
10
  function resolve(middlewares, context) {
16
- const next = /* @__PURE__ */ __name(() => {
11
+ const next = () => {
17
12
  const { value: nextMiddleware, done } = middlewares.next();
18
13
  if (done || !nextMiddleware) {
19
14
  throw new Error("no more next middleware");
20
15
  } else {
21
16
  return nextMiddleware(context, next);
22
17
  }
23
- }, "next");
18
+ };
24
19
  return next();
25
20
  }
26
- __name(resolve, "resolve");
27
21
  export {
28
22
  MiddlewareChain,
29
23
  resolve
@@ -1,5 +1,3 @@
1
- var __defProp = Object.defineProperty;
2
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
1
  import { getContent, fromContent } from "../xml/index.js";
4
2
  function registerBuiltIns(create) {
5
3
  create(String, {
@@ -39,7 +37,6 @@ function registerBuiltIns(create) {
39
37
  }
40
38
  });
41
39
  }
42
- __name(registerBuiltIns, "registerBuiltIns");
43
40
  export {
44
41
  registerBuiltIns as default
45
42
  };
@@ -1,19 +1,67 @@
1
1
  import { Constructor } from 'typescript-rtti';
2
2
  import { XMLModelOptions, XMLModelPropertyOptions, CreateXMLModelOptions } from './types';
3
3
  import { XMLRoot } from '../types';
4
+ /**
5
+ * Returns the parent `XMLModel` for the given model, walking the prototype chain
6
+ * if no explicit parent was set in options.
7
+ */
4
8
  export declare function getParentModel(model: XMLModel<any>): XMLModel<any>;
9
+ /**
10
+ * Encapsulates the XML ↔ TypeScript conversion logic for a specific class.
11
+ *
12
+ * Create instances via `createModel` or the `@Model()` decorator rather than
13
+ * calling this constructor directly.
14
+ */
5
15
  export declare class XMLModel<T = any> {
6
16
  readonly type: Constructor<T>;
7
17
  options: XMLModelOptions<T>;
8
18
  constructor(type: Constructor<T>, options: CreateXMLModelOptions<T>);
19
+ /**
20
+ * Converts an XML document (string or parsed `XMLRoot`) into an instance of `T`.
21
+ *
22
+ * @param xml - Raw XML string or a pre-parsed `XMLRoot` object.
23
+ * @returns The converted instance produced by the model's `fromXML` middleware chain.
24
+ * @throws {FromXMLConversionError} When model-level conversion fails.
25
+ * @throws {PropertyFromXMLConversionError} When a property-level conversion fails.
26
+ */
9
27
  fromXML(xml: XMLRoot | string): T;
28
+ /**
29
+ * Converts an instance of `T` into an XML document.
30
+ *
31
+ * @param instance - An instance of the class this model was created for.
32
+ * @returns An `XMLRoot` representing the serialised object.
33
+ * @throws {TypeError} When `instance` is not an instance of the expected type.
34
+ * @throws {ToXMLConversionError} When model-level conversion fails.
35
+ * @throws {PropertyToXMLConversionError} When a property-level conversion fails.
36
+ */
10
37
  toXML(instance: unknown): XMLRoot;
38
+ /** The typescript-rtti reflection metadata for the model's class. */
11
39
  get reflectedClass(): import('typescript-rtti').ReflectedClass<Constructor<T>>;
40
+ /**
41
+ * Returns a merged map of all property options for this model, including inherited properties.
42
+ * Own properties override parent properties with the same name.
43
+ */
12
44
  resolveAllProperties(): Map<string, XMLModelPropertyOptions<any> & {
13
45
  model: any;
14
46
  }>;
15
47
  }
48
+ /**
49
+ * Creates and registers a new `XMLModel` for the given constructor.
50
+ *
51
+ * @param type - The class constructor to create a model for.
52
+ * @param options - Model creation options including `fromXML` and `toXML` middlewares.
53
+ * @returns The newly created `XMLModel`.
54
+ * @throws {TypeError} When a model for this type has already been registered.
55
+ */
16
56
  export declare function createModel<T>(type: Constructor<T>, options: CreateXMLModelOptions<T>): XMLModel<T>;
57
+ /**
58
+ * Decorator factory that registers an `XMLModel` for the decorated class.
59
+ *
60
+ * Provide at minimum a `fromXML` function unless the class inherits from a
61
+ * parent class that already has a model — the default `fromXML` throws.
62
+ *
63
+ * @param options - Optional model creation options.
64
+ */
17
65
  declare function ModelDecoratorFactory<T>(options?: CreateXMLModelOptions<T>): (constructor: Constructor<T>) => void;
18
66
  export { getModel } from './registry';
19
67
  export { ModelDecoratorFactory as Model };
@@ -1,5 +1,3 @@
1
- var __defProp = Object.defineProperty;
2
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
1
  import "../_virtual/Reflect.js";
4
2
  import { reflect } from "typescript-rtti";
5
3
  import { ToXMLConversionError, PropertyToXMLConversionError, FromXMLConversionError, PropertyFromXMLConversionError } from "../errors.js";
@@ -27,10 +25,8 @@ function* ParentChain(constructor) {
27
25
  }
28
26
  return;
29
27
  }
30
- __name(ParentChain, "ParentChain");
31
28
  function getParentModel(model) {
32
- if (model.options.parent)
33
- return model.options.parent;
29
+ if (model.options.parent) return model.options.parent;
34
30
  for (const constructor of ParentChain(model.type)) {
35
31
  const model2 = findModel(constructor);
36
32
  if (model2) {
@@ -39,17 +35,15 @@ function getParentModel(model) {
39
35
  }
40
36
  return null;
41
37
  }
42
- __name(getParentModel, "getParentModel");
43
- const _XMLModel = class _XMLModel {
38
+ class XMLModel {
44
39
  constructor(type, options) {
45
40
  this.type = type;
46
41
  const model = this;
47
42
  let parent = void 0;
48
- const getParent = /* @__PURE__ */ __name(() => {
49
- if (typeof parent === "undefined")
50
- parent = getParentModel(this);
43
+ const getParent = () => {
44
+ if (typeof parent === "undefined") parent = getParentModel(this);
51
45
  return parent;
52
- }, "getParent");
46
+ };
53
47
  let propertiesLoaded = false;
54
48
  const properties = {
55
49
  options: /* @__PURE__ */ new Map(),
@@ -116,20 +110,30 @@ const _XMLModel = class _XMLModel {
116
110
  ]
117
111
  }
118
112
  };
119
- const loadProperties = /* @__PURE__ */ __name(() => {
120
- const props = this.reflectedClass.ownProperties.filter((prop) => typeof prop.host.constructor.prototype[prop.name] !== "function");
113
+ const loadProperties = () => {
114
+ const props = this.reflectedClass.ownProperties.filter(
115
+ (prop) => typeof prop.host.constructor.prototype[prop.name] !== "function"
116
+ );
121
117
  props.forEach((property) => {
122
- const options2 = getPropertyConversionOptions(this.type, property.name);
118
+ const options2 = getPropertyConversionOptions(
119
+ this.type,
120
+ property.name
121
+ );
123
122
  if (!options2.ignored) {
123
+ const type2 = options2.reflected?.type;
124
+ if (!options2.model && type2?.is("class") && type2.class === Object) {
125
+ console.warn(
126
+ `[xml-model] Property '${String(property.name)}' on '${this.type.name}' has type Object at runtime. If its declared type is a class, make sure it is imported as a value and not with 'import type'.`
127
+ );
128
+ }
124
129
  properties.options.set(property.name, options2);
125
130
  }
126
131
  });
127
132
  propertiesLoaded = true;
128
- }, "loadProperties");
133
+ };
129
134
  this.options = {
130
135
  get properties() {
131
- if (!propertiesLoaded)
132
- loadProperties();
136
+ if (!propertiesLoaded) loadProperties();
133
137
  return properties;
134
138
  },
135
139
  fromXML: {
@@ -148,17 +152,22 @@ const _XMLModel = class _XMLModel {
148
152
  return options.tagname || defaults.tagnameFromModel(model);
149
153
  }
150
154
  };
151
- if (options.parent)
152
- this.options.parent = options.parent;
155
+ if (options.parent) this.options.parent = options.parent;
153
156
  if (!getParent()) {
154
157
  this.options.fromXML.middlewares.push((ctx) => defaults.fromXML(ctx));
155
158
  this.options.toXML.middlewares.push((ctx) => defaults.toXML(ctx));
156
159
  }
157
- if (options.fromXML)
158
- this.options.fromXML.middlewares.push(options.fromXML);
159
- if (options.toXML)
160
- this.options.toXML.middlewares.push(options.toXML);
160
+ if (options.fromXML) this.options.fromXML.middlewares.push(options.fromXML);
161
+ if (options.toXML) this.options.toXML.middlewares.push(options.toXML);
161
162
  }
163
+ /**
164
+ * Converts an XML document (string or parsed `XMLRoot`) into an instance of `T`.
165
+ *
166
+ * @param xml - Raw XML string or a pre-parsed `XMLRoot` object.
167
+ * @returns The converted instance produced by the model's `fromXML` middleware chain.
168
+ * @throws {FromXMLConversionError} When model-level conversion fails.
169
+ * @throws {PropertyFromXMLConversionError} When a property-level conversion fails.
170
+ */
162
171
  fromXML(xml) {
163
172
  const _xml = typeof xml === "string" ? XML.parse(xml) : xml;
164
173
  const model = this;
@@ -175,6 +184,15 @@ const _XMLModel = class _XMLModel {
175
184
  };
176
185
  return resolve(MiddlewareChain(this.options.fromXML), context);
177
186
  }
187
+ /**
188
+ * Converts an instance of `T` into an XML document.
189
+ *
190
+ * @param instance - An instance of the class this model was created for.
191
+ * @returns An `XMLRoot` representing the serialised object.
192
+ * @throws {TypeError} When `instance` is not an instance of the expected type.
193
+ * @throws {ToXMLConversionError} When model-level conversion fails.
194
+ * @throws {PropertyToXMLConversionError} When a property-level conversion fails.
195
+ */
178
196
  toXML(instance) {
179
197
  const model = this;
180
198
  if (instance instanceof this.type || typeof instance !== "undefined" && instance.constructor === this.type) {
@@ -194,28 +212,33 @@ const _XMLModel = class _XMLModel {
194
212
  throw new TypeError(`provided object is not an instance of ${this.type.name}`);
195
213
  }
196
214
  }
215
+ /** The typescript-rtti reflection metadata for the model's class. */
197
216
  get reflectedClass() {
198
217
  return reflect(this.type);
199
218
  }
219
+ /**
220
+ * Returns a merged map of all property options for this model, including inherited properties.
221
+ * Own properties override parent properties with the same name.
222
+ */
200
223
  resolveAllProperties() {
201
224
  const ownProperties = /* @__PURE__ */ new Map();
202
225
  const parent = getParentModel(this);
203
226
  this.options.properties.options.forEach((options, key) => {
204
- ownProperties.set(key, new Proxy(options, {
205
- get: /* @__PURE__ */ __name((target, p, reciever) => {
206
- if (p === "model")
207
- return this;
208
- else
209
- return Reflect.get(target, p, reciever);
210
- }, "get")
211
- }));
227
+ ownProperties.set(
228
+ key,
229
+ new Proxy(options, {
230
+ get: (target, p, reciever) => {
231
+ if (p === "model") return this;
232
+ else return Reflect.get(target, p, reciever);
233
+ }
234
+ })
235
+ // FIXME: is typing ok ?
236
+ );
212
237
  });
213
238
  const res = parent ? mergeMaps(parent.resolveAllProperties(), ownProperties) : ownProperties;
214
239
  return res;
215
240
  }
216
- };
217
- __name(_XMLModel, "XMLModel");
218
- let XMLModel = _XMLModel;
241
+ }
219
242
  function createModel(type, options) {
220
243
  if (findModel(type)) {
221
244
  throw new TypeError(`a model for type ${type.name} already exists`);
@@ -224,14 +247,11 @@ function createModel(type, options) {
224
247
  registrerModel(model);
225
248
  return model;
226
249
  }
227
- __name(createModel, "createModel");
228
250
  function ModelDecoratorFactory(options) {
229
251
  return function(constructor) {
230
- if (!findModel(constructor))
231
- createModel(constructor, options || {});
252
+ if (!findModel(constructor)) createModel(constructor, options || {});
232
253
  };
233
254
  }
234
- __name(ModelDecoratorFactory, "ModelDecoratorFactory");
235
255
  registerBuiltIns(createModel);
236
256
  export {
237
257
  ModelDecoratorFactory as Model,
@@ -1,6 +1,18 @@
1
1
  import { Constructor } from 'typescript-rtti';
2
2
  import { XMLModelProperty, XMLModelPropertyOptions, CreateXMLModelPropertyOptions } from './types';
3
+ /**
4
+ * Returns the resolved conversion options for a property, using stored `@Prop()` options
5
+ * if available, or falling back to defaults derived from the property's type information.
6
+ */
3
7
  export declare function getPropertyConversionOptions<T>(constructor: Constructor<T>, property: XMLModelProperty<T>): XMLModelPropertyOptions<T>;
8
+ /**
9
+ * Decorator factory that customises how a class property is converted to and from XML.
10
+ *
11
+ * Applied to properties of classes decorated with `@Model()`. All options are optional —
12
+ * omitting `@Prop()` entirely uses the defaults inferred from the property's TypeScript type.
13
+ *
14
+ * @param options - Property conversion options.
15
+ */
4
16
  declare function PropDecoratorFactory<T = any>(options?: CreateXMLModelPropertyOptions<T>): (prototype: any, property: XMLModelProperty<T>) => void;
5
17
  export { PropDecoratorFactory as Prop };
6
18
  //# sourceMappingURL=property.d.ts.map
@@ -1,5 +1,3 @@
1
- var __defProp = Object.defineProperty;
2
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
1
  import { reflect } from "typescript-rtti";
4
2
  import { defaults } from "../defaults.js";
5
3
  import isRegExp from "../util/is-regexp.js";
@@ -15,13 +13,12 @@ function resolvePropertyConversionOptions(options, constructor, property) {
15
13
  },
16
14
  inline: !!options.inline,
17
15
  ignored: !!options.ignore,
18
- isSourceElement: /* @__PURE__ */ __name((...args) => defaults.propertySourceElementsFilter(...args), "isSourceElement"),
16
+ isSourceElement: (...args) => defaults.propertySourceElementsFilter(...args),
19
17
  resolveElements: options.resolveElements ? options.resolveElements : (...args) => defaults.propertyResolveSourceElements(...args),
20
- fromXML: /* @__PURE__ */ __name((context) => (options.fromXML ?? defaults.propertyFromXML)(context), "fromXML"),
21
- toXML: /* @__PURE__ */ __name((context) => (options.toXML ?? defaults.propertyToXML)(context), "toXML")
18
+ fromXML: (context) => (options.fromXML ?? defaults.propertyFromXML)(context),
19
+ toXML: (context) => (options.toXML ?? defaults.propertyToXML)(context)
22
20
  };
23
- if (options?.model)
24
- _options.model = options.model;
21
+ if (options?.model) _options.model = options.model;
25
22
  if (options?.sourceElements) {
26
23
  const _sourceElements = options.sourceElements;
27
24
  if (typeof _sourceElements === "string") {
@@ -34,7 +31,6 @@ function resolvePropertyConversionOptions(options, constructor, property) {
34
31
  }
35
32
  return _options;
36
33
  }
37
- __name(resolvePropertyConversionOptions, "resolvePropertyConversionOptions");
38
34
  const PropertyOptions = /* @__PURE__ */ new Map();
39
35
  function storePropertyConversionOptions(constructor, property, options) {
40
36
  let map = PropertyOptions.get(constructor);
@@ -44,26 +40,26 @@ function storePropertyConversionOptions(constructor, property, options) {
44
40
  }
45
41
  map.set(property, options);
46
42
  }
47
- __name(storePropertyConversionOptions, "storePropertyConversionOptions");
48
43
  function findPropertyConversionOptions(constructor, property) {
49
44
  const options = PropertyOptions.get(constructor);
50
45
  if (options) {
51
46
  return options.get(property);
52
47
  }
53
48
  }
54
- __name(findPropertyConversionOptions, "findPropertyConversionOptions");
55
49
  function getPropertyConversionOptions(constructor, property) {
56
50
  const options = findPropertyConversionOptions(constructor, property);
57
51
  return options ?? resolvePropertyConversionOptions({}, constructor, property);
58
52
  }
59
- __name(getPropertyConversionOptions, "getPropertyConversionOptions");
60
53
  function PropDecoratorFactory(options) {
61
54
  return function(prototype, property) {
62
- const _options = resolvePropertyConversionOptions(options ?? {}, prototype.constructor, property);
55
+ const _options = resolvePropertyConversionOptions(
56
+ options ?? {},
57
+ prototype.constructor,
58
+ property
59
+ );
63
60
  storePropertyConversionOptions(prototype.constructor, property, _options);
64
61
  };
65
62
  }
66
- __name(PropDecoratorFactory, "PropDecoratorFactory");
67
63
  export {
68
64
  PropDecoratorFactory as Prop,
69
65
  getPropertyConversionOptions