xml-model 0.3.0 → 1.0.0
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.
- package/README.md +46 -1
- package/dist/defaults.d.ts +14 -0
- package/dist/defaults.js +129 -0
- package/{build/main → dist}/errors.d.ts +1 -1
- package/dist/errors.js +51 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +19 -0
- package/{build/main → dist}/middleware.d.ts +2 -2
- package/dist/middleware.js +31 -0
- package/dist/model/built-ins.d.ts +2 -0
- package/dist/model/built-ins.js +46 -0
- package/{build/module → dist}/model/index.d.ts +7 -11
- package/dist/model/index.js +242 -0
- package/{build/main → dist}/model/property.d.ts +2 -2
- package/dist/model/property.js +71 -0
- package/dist/model/registry.d.ts +8 -0
- package/dist/model/registry.js +26 -0
- package/{build/module → dist}/model/types.d.ts +7 -7
- package/dist/model/types.js +2 -0
- package/{build/module → dist}/types.d.ts +4 -4
- package/dist/types.js +2 -0
- package/dist/util/is-regexp.d.ts +11 -0
- package/dist/util/is-regexp.js +11 -0
- package/dist/util/kebab-case.d.ts +15 -0
- package/dist/util/kebab-case.js +18 -0
- package/dist/util/merge-maps.js +27 -0
- package/{build/main → dist}/xml/index.d.ts +4 -4
- package/dist/xml/index.js +73 -0
- package/{build/main → dist}/xml/xml-js.d.ts +1 -4
- package/dist/xml/xml-js.js +9 -0
- package/package.json +56 -39
- package/vite/dist/_virtual/_commonjs-dynamic-modules.js +7 -0
- package/vite/dist/_virtual/_commonjsHelpers.js +47 -0
- package/vite/dist/_virtual/_typescript.js +5 -0
- package/vite/dist/_virtual/api-call-transformer.js +5 -0
- package/vite/dist/_virtual/class-analyzer.js +5 -0
- package/vite/dist/_virtual/compile-error.js +5 -0
- package/vite/dist/_virtual/declarations-emitter.js +5 -0
- package/vite/dist/_virtual/encode-parameter.js +5 -0
- package/vite/dist/_virtual/find-relative-path.js +5 -0
- package/vite/dist/_virtual/flags.js +5 -0
- package/vite/dist/_virtual/format.js +5 -0
- package/vite/dist/_virtual/forward-ref.js +5 -0
- package/vite/dist/_virtual/get-exports-for-symbol.js +5 -0
- package/vite/dist/_virtual/import-analyzer.js +5 -0
- package/vite/dist/_virtual/index.js +8 -0
- package/vite/dist/_virtual/index2.js +5 -0
- package/vite/dist/_virtual/index3.js +5 -0
- package/vite/dist/_virtual/interface-analyzer.js +5 -0
- package/vite/dist/_virtual/legacy-decorator.js +5 -0
- package/vite/dist/_virtual/legacy-type-encoder.js +5 -0
- package/vite/dist/_virtual/literal-node.js +5 -0
- package/vite/dist/_virtual/metadata-collector.js +5 -0
- package/vite/dist/_virtual/metadata-decorator.js +5 -0
- package/vite/dist/_virtual/metadata-emitter.js +5 -0
- package/vite/dist/_virtual/metadata-encoder.js +5 -0
- package/vite/dist/_virtual/rt-helper.js +5 -0
- package/vite/dist/_virtual/rtti-visitor-base.js +5 -0
- package/vite/dist/_virtual/serialize.js +5 -0
- package/vite/dist/_virtual/type-encoder.js +5 -0
- package/vite/dist/_virtual/type-literal.js +5 -0
- package/vite/dist/_virtual/utils.js +5 -0
- package/vite/dist/_virtual/visitor-base.js +5 -0
- package/vite/dist/_virtual/workarounds.js +5 -0
- package/vite/dist/index.d.ts +21 -0
- package/vite/dist/index.js +62 -0
- package/vite/dist/node_modules/typescript-rtti/dist/common/format.js +69 -0
- package/vite/dist/node_modules/typescript-rtti/dist/common/index.js +34 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/api-call-transformer.js +197 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/common/class-analyzer.js +124 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/common/compile-error.js +18 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/common/import-analyzer.js +130 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/common/interface-analyzer.js +98 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/common/visitor-base.js +132 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/declarations-emitter.js +72 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/encode-parameter.js +110 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/find-relative-path.js +51 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/flags.js +59 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/forward-ref.js +35 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/get-exports-for-symbol.js +75 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/index.js +174 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/legacy-decorator.js +20 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/legacy-type-encoder.js +123 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/literal-node.js +19 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/metadata-collector.js +96 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/metadata-decorator.js +99 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/metadata-emitter.js +475 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/metadata-encoder.js +261 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/rt-helper.js +113 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/rtti-visitor-base.js +39 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/serialize.js +46 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/type-encoder.js +96 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/type-literal.js +546 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/utils.js +922 -0
- package/vite/dist/node_modules/typescript-rtti/dist/transformer/workarounds.js +16 -0
- package/build/main/defaults/index.d.ts +0 -14
- package/build/main/defaults/index.js +0 -170
- package/build/main/defaults/models.d.ts +0 -1
- package/build/main/defaults/models.js +0 -55
- package/build/main/errors.js +0 -93
- package/build/main/helper/merge-maps.js +0 -42
- package/build/main/index.d.ts +0 -6
- package/build/main/index.js +0 -46
- package/build/main/middleware.js +0 -61
- package/build/main/model/index.d.ts +0 -23
- package/build/main/model/index.js +0 -342
- package/build/main/model/property.js +0 -100
- package/build/main/model/types.d.ts +0 -73
- package/build/main/model/types.js +0 -152
- package/build/main/types.d.ts +0 -16
- package/build/main/types.js +0 -41
- package/build/main/xml/index.js +0 -105
- package/build/main/xml/xml-js.js +0 -26
- package/build/module/defaults/index.d.ts +0 -14
- package/build/module/defaults/index.js +0 -164
- package/build/module/defaults/models.d.ts +0 -1
- package/build/module/defaults/models.js +0 -54
- package/build/module/errors.d.ts +0 -23
- package/build/module/errors.js +0 -89
- package/build/module/helper/merge-maps.d.ts +0 -1
- package/build/module/helper/merge-maps.js +0 -39
- package/build/module/index.d.ts +0 -6
- package/build/module/index.js +0 -21
- package/build/module/middleware.d.ts +0 -9
- package/build/module/middleware.js +0 -56
- package/build/module/model/index.js +0 -334
- package/build/module/model/property.d.ts +0 -5
- package/build/module/model/property.js +0 -99
- package/build/module/model/types.js +0 -152
- package/build/module/types.js +0 -38
- package/build/module/xml/index.d.ts +0 -32
- package/build/module/xml/index.js +0 -94
- package/build/module/xml/xml-js.d.ts +0 -9
- package/build/module/xml/xml-js.js +0 -24
- /package/{build/main/helper → dist/util}/merge-maps.d.ts +0 -0
package/README.md
CHANGED
|
@@ -1,7 +1,52 @@
|
|
|
1
1
|
# XML Model
|
|
2
2
|
|
|
3
3
|
## Usage
|
|
4
|
+
|
|
4
5
|
needs [typescript-rtti](https://github.com/typescript-rtti/typescript-rtti) and [ttypescript](https://github.com/cevek/ttypescript) to work
|
|
5
6
|
|
|
7
|
+
To build something that relies in `xml-model` with vite
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { defineConfig } from "vite";
|
|
11
|
+
import XMLModelVitePlugin from "xml-model/vite";
|
|
12
|
+
|
|
13
|
+
export default defineConfig({
|
|
14
|
+
plugins: [
|
|
15
|
+
// see options in JSDoc
|
|
16
|
+
XMLModelVitePlugin(),
|
|
17
|
+
],
|
|
18
|
+
// ... rest of the config
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
6
22
|
## Documentation
|
|
7
|
-
|
|
23
|
+
|
|
24
|
+
### Example
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import "reflect-metadata";
|
|
28
|
+
import { Model, getModel, XML } from "xml-model";
|
|
29
|
+
|
|
30
|
+
@Model({
|
|
31
|
+
fromXML(ctx) {
|
|
32
|
+
const instance = new MyClass();
|
|
33
|
+
if (ctx.properties.foo) instance.foo = ctx.properties.foo;
|
|
34
|
+
return instance;
|
|
35
|
+
},
|
|
36
|
+
})
|
|
37
|
+
class MyClass {
|
|
38
|
+
foo = "bar";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const model = getModel(MyClass);
|
|
42
|
+
|
|
43
|
+
const a: MyClass = model.fromXML("<my-class><foo>test</foo></my-class>");
|
|
44
|
+
console.log(JSON.stringify(a)); // {"foo":"test"}
|
|
45
|
+
|
|
46
|
+
const b = new MyClass();
|
|
47
|
+
console.log(XML.stringify(model.toXML(b))); // <my-class><foo>bar</foo></my-class>
|
|
48
|
+
b.foo = "other";
|
|
49
|
+
console.log(XML.stringify(model.toXML(b))); // <my-class><foo>other</foo></my-class>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
See [source code](https://github.com/MathisTLD/xml-model) for more
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { fromXMLContext, PropertyFromXMLContext, PropertyToXMLContext, toXMLContext, XMLModelPropertyOptions, XMLModel } from './model/types';
|
|
2
|
+
import { XMLElement, XMLRoot } from './types';
|
|
3
|
+
interface Defaults {
|
|
4
|
+
fromXML<T>(context: fromXMLContext<T>): T;
|
|
5
|
+
propertySourceElementsFilter<T>(...args: Parameters<XMLModelPropertyOptions<T>["isSourceElement"]>): boolean;
|
|
6
|
+
propertyResolveSourceElements<T>(context: Omit<PropertyFromXMLContext<T>, "elements">): XMLElement[];
|
|
7
|
+
propertyFromXML<T>(context: PropertyFromXMLContext<T>): T[keyof T];
|
|
8
|
+
toXML<T>(context: toXMLContext<T>): XMLRoot;
|
|
9
|
+
tagnameFromModel: (model: XMLModel) => string;
|
|
10
|
+
tagnameFromProperty<T>(property: XMLModelPropertyOptions<T>): string;
|
|
11
|
+
propertyToXML<T>(context: PropertyToXMLContext<T>): XMLRoot;
|
|
12
|
+
}
|
|
13
|
+
export declare const defaults: Defaults;
|
|
14
|
+
export {};
|
package/dist/defaults.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
import { getModel } from "./model/registry.js";
|
|
4
|
+
import { kebabCase } from "./util/kebab-case.js";
|
|
5
|
+
const defaults = {
|
|
6
|
+
fromXML() {
|
|
7
|
+
throw new TypeError("you should define 'defaults.fromXML' yourself or provide a 'fromXML' function to @Model() decorator's options");
|
|
8
|
+
},
|
|
9
|
+
propertyResolveSourceElements(context) {
|
|
10
|
+
const innerElements = context.xml.elements[0]?.elements || [];
|
|
11
|
+
return innerElements.filter((el) => context.property.isSourceElement(el, context));
|
|
12
|
+
},
|
|
13
|
+
propertySourceElementsFilter(element, context) {
|
|
14
|
+
return context.property.tagname === element.name;
|
|
15
|
+
},
|
|
16
|
+
propertyFromXML(context) {
|
|
17
|
+
const prop = context.property;
|
|
18
|
+
const elements = context.elements;
|
|
19
|
+
if (prop.reflected.isOptional && elements.length === 0) {
|
|
20
|
+
return void 0;
|
|
21
|
+
}
|
|
22
|
+
if (prop.model) {
|
|
23
|
+
return prop.model.fromXML({ elements });
|
|
24
|
+
}
|
|
25
|
+
const type = context.property.reflected.type;
|
|
26
|
+
if (type.is("class")) {
|
|
27
|
+
const model = getModel(type.class);
|
|
28
|
+
return model.fromXML({ elements: context.elements });
|
|
29
|
+
} else if (type.is("array")) {
|
|
30
|
+
let arrayEl = {};
|
|
31
|
+
if (!prop.inline && elements.length === 1 && elements[0].name === prop.tagname) {
|
|
32
|
+
arrayEl = elements[0];
|
|
33
|
+
} else if (prop.inline) {
|
|
34
|
+
arrayEl = { elements };
|
|
35
|
+
}
|
|
36
|
+
const els = arrayEl.elements || [];
|
|
37
|
+
const elType = type.elementType;
|
|
38
|
+
if (elType.is("class")) {
|
|
39
|
+
const model = getModel(elType.class);
|
|
40
|
+
const xmlInstances = els.map((el) => ({
|
|
41
|
+
elements: [el]
|
|
42
|
+
}));
|
|
43
|
+
return xmlInstances.map((xml) => model.fromXML(xml));
|
|
44
|
+
}
|
|
45
|
+
} else if (type.is("union") && type.types.length && type.types[0].is("literal")) {
|
|
46
|
+
const firstType = type.types[0];
|
|
47
|
+
if (firstType.is("literal")) {
|
|
48
|
+
const firstTypeCtor = firstType.value.constructor;
|
|
49
|
+
if (type.types.every((type2) => type2.is("literal") && type2.value.constructor === firstTypeCtor)) {
|
|
50
|
+
const model = getModel(firstTypeCtor);
|
|
51
|
+
return model.fromXML({ elements });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return void 0;
|
|
56
|
+
},
|
|
57
|
+
/* Object -> XML */
|
|
58
|
+
toXML({ properties, model }) {
|
|
59
|
+
const elements = [];
|
|
60
|
+
model.resolveAllProperties().forEach((prop) => {
|
|
61
|
+
if (prop.name in properties && typeof prop.name !== "symbol") {
|
|
62
|
+
const _xml = properties[prop.name];
|
|
63
|
+
_xml.elements.forEach((el) => {
|
|
64
|
+
el.name = prop.tagname;
|
|
65
|
+
elements.push(el);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
return {
|
|
70
|
+
elements: [
|
|
71
|
+
{
|
|
72
|
+
type: "element",
|
|
73
|
+
name: model.options.tagname,
|
|
74
|
+
elements
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
};
|
|
78
|
+
},
|
|
79
|
+
tagnameFromModel(model) {
|
|
80
|
+
return kebabCase(model.type.name);
|
|
81
|
+
},
|
|
82
|
+
tagnameFromProperty(property) {
|
|
83
|
+
return kebabCase(String(property.name));
|
|
84
|
+
},
|
|
85
|
+
propertyToXML(context) {
|
|
86
|
+
const property = context.property;
|
|
87
|
+
const type = property.reflected.type;
|
|
88
|
+
const value = context.value;
|
|
89
|
+
if (property.reflected.isOptional && typeof value === "undefined") {
|
|
90
|
+
return { elements: [] };
|
|
91
|
+
}
|
|
92
|
+
if (property.model) {
|
|
93
|
+
return property.model.toXML(value);
|
|
94
|
+
}
|
|
95
|
+
const getXML = /* @__PURE__ */ __name(() => {
|
|
96
|
+
if (type.is("class")) {
|
|
97
|
+
const model = getModel(type.class);
|
|
98
|
+
return model.toXML(value);
|
|
99
|
+
} else if (type.is("array")) {
|
|
100
|
+
const elementType = type.elementType;
|
|
101
|
+
if (elementType.is("class")) {
|
|
102
|
+
const model = getModel(elementType.class);
|
|
103
|
+
const elements = [];
|
|
104
|
+
value.forEach((el) => elements.push(...model.toXML(el).elements));
|
|
105
|
+
return { elements: [{ type: "element", name: "array", elements }] };
|
|
106
|
+
}
|
|
107
|
+
} else if (type.is("union") && type.types.length && type.types[0].is("literal")) {
|
|
108
|
+
const firstType = type.types[0];
|
|
109
|
+
if (firstType.is("literal")) {
|
|
110
|
+
const firstTypeCtor = firstType.value.constructor;
|
|
111
|
+
if (type.types.every((type2) => type2.is("literal") && type2.value.constructor === firstTypeCtor)) {
|
|
112
|
+
const model = getModel(firstTypeCtor);
|
|
113
|
+
return model.toXML(context.value);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return { elements: [] };
|
|
118
|
+
}, "getXML");
|
|
119
|
+
const xml = getXML();
|
|
120
|
+
if (context.property.inline)
|
|
121
|
+
return { elements: xml.elements.map((el) => el.elements || []).flat() };
|
|
122
|
+
else
|
|
123
|
+
return xml;
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
export {
|
|
127
|
+
defaults
|
|
128
|
+
};
|
|
129
|
+
//# sourceMappingURL=defaults.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { fromXMLContext, PropertyFromXMLContext, PropertyToXMLContext, toXMLContext } from
|
|
1
|
+
import { fromXMLContext, PropertyFromXMLContext, PropertyToXMLContext, toXMLContext } from './model/types';
|
|
2
2
|
export declare class FromXMLConversionError<T> extends Error {
|
|
3
3
|
context: Omit<fromXMLContext<T>, "properties">;
|
|
4
4
|
error: unknown;
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
const _FromXMLConversionError = class _FromXMLConversionError extends Error {
|
|
4
|
+
constructor(context, error) {
|
|
5
|
+
const message = `[Model: ${context.model.type.name}] failed to convert from XML`;
|
|
6
|
+
super(message);
|
|
7
|
+
this.context = context;
|
|
8
|
+
this.error = error;
|
|
9
|
+
this.name = "FromXMLConversionError";
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
__name(_FromXMLConversionError, "FromXMLConversionError");
|
|
13
|
+
let FromXMLConversionError = _FromXMLConversionError;
|
|
14
|
+
const _PropertyFromXMLConversionError = class _PropertyFromXMLConversionError extends FromXMLConversionError {
|
|
15
|
+
constructor(context, propertyContext, error) {
|
|
16
|
+
super(context, error);
|
|
17
|
+
this.propertyContext = propertyContext;
|
|
18
|
+
this.name = "PropertyFromXMLConversionError";
|
|
19
|
+
this.message = `[Model: ${context.model.type.name}] failed to convert prop <${String(propertyContext.property.name)}> from XML`;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
__name(_PropertyFromXMLConversionError, "PropertyFromXMLConversionError");
|
|
23
|
+
let PropertyFromXMLConversionError = _PropertyFromXMLConversionError;
|
|
24
|
+
const _ToXMLConversionError = class _ToXMLConversionError extends Error {
|
|
25
|
+
constructor(context, cause) {
|
|
26
|
+
const message = `[Model: ${context.model.type.name}] failed to convert to XML`;
|
|
27
|
+
super(message);
|
|
28
|
+
this.context = context;
|
|
29
|
+
this.cause = cause;
|
|
30
|
+
this.name = "ToXMLConversionError";
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
__name(_ToXMLConversionError, "ToXMLConversionError");
|
|
34
|
+
let ToXMLConversionError = _ToXMLConversionError;
|
|
35
|
+
const _PropertyToXMLConversionError = class _PropertyToXMLConversionError extends ToXMLConversionError {
|
|
36
|
+
constructor(context, propertyContext, cause) {
|
|
37
|
+
super(context, cause);
|
|
38
|
+
this.propertyContext = propertyContext;
|
|
39
|
+
this.name = "PropertyToXMLConversionError";
|
|
40
|
+
this.message = `[Model: ${context.model.type.name}] failed to convert prop <${String(propertyContext.property.name)}> to XML`;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
__name(_PropertyToXMLConversionError, "PropertyToXMLConversionError");
|
|
44
|
+
let PropertyToXMLConversionError = _PropertyToXMLConversionError;
|
|
45
|
+
export {
|
|
46
|
+
FromXMLConversionError,
|
|
47
|
+
PropertyFromXMLConversionError,
|
|
48
|
+
PropertyToXMLConversionError,
|
|
49
|
+
ToXMLConversionError
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=errors.js.map
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { defaults } from "./defaults.js";
|
|
2
|
+
import { Model, createModel } from "./model/index.js";
|
|
3
|
+
import { FromXMLConversionError, PropertyFromXMLConversionError, PropertyToXMLConversionError, ToXMLConversionError } from "./errors.js";
|
|
4
|
+
import { default as default2 } from "./xml/index.js";
|
|
5
|
+
import { Prop } from "./model/property.js";
|
|
6
|
+
import { getModel } from "./model/registry.js";
|
|
7
|
+
export {
|
|
8
|
+
FromXMLConversionError,
|
|
9
|
+
Model,
|
|
10
|
+
Prop,
|
|
11
|
+
PropertyFromXMLConversionError,
|
|
12
|
+
PropertyToXMLConversionError,
|
|
13
|
+
ToXMLConversionError,
|
|
14
|
+
default2 as XML,
|
|
15
|
+
createModel,
|
|
16
|
+
defaults,
|
|
17
|
+
getModel
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type Middleware<C, T> = (context: C, next: () => T) => T;
|
|
2
2
|
interface ChainableOptions<C, T> {
|
|
3
3
|
parent: ChainableOptions<C, T> | null;
|
|
4
4
|
middlewares: Middleware<C, T>[];
|
|
5
5
|
}
|
|
6
6
|
export declare function MiddlewareChain<C, T>(options: ChainableOptions<C, T>): Generator<Middleware<C, T>, void, unknown>;
|
|
7
|
-
|
|
7
|
+
type MiddlewareChain<C, T> = Iterator<Middleware<C, T>>;
|
|
8
8
|
export declare function resolve<C, T>(middlewares: MiddlewareChain<C, T>, context: C): T;
|
|
9
9
|
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
function* MiddlewareChain(options) {
|
|
4
|
+
do {
|
|
5
|
+
for (let index = options.middlewares.length - 1; index >= 0; index--) {
|
|
6
|
+
yield options.middlewares[index];
|
|
7
|
+
}
|
|
8
|
+
if (options.parent)
|
|
9
|
+
options = options.parent;
|
|
10
|
+
else
|
|
11
|
+
return;
|
|
12
|
+
} while (true);
|
|
13
|
+
}
|
|
14
|
+
__name(MiddlewareChain, "MiddlewareChain");
|
|
15
|
+
function resolve(middlewares, context) {
|
|
16
|
+
const next = /* @__PURE__ */ __name(() => {
|
|
17
|
+
const { value: nextMiddleware, done } = middlewares.next();
|
|
18
|
+
if (done || !nextMiddleware) {
|
|
19
|
+
throw new Error("no more next middleware");
|
|
20
|
+
} else {
|
|
21
|
+
return nextMiddleware(context, next);
|
|
22
|
+
}
|
|
23
|
+
}, "next");
|
|
24
|
+
return next();
|
|
25
|
+
}
|
|
26
|
+
__name(resolve, "resolve");
|
|
27
|
+
export {
|
|
28
|
+
MiddlewareChain,
|
|
29
|
+
resolve
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=middleware.js.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
import { getContent, fromContent } from "../xml/index.js";
|
|
4
|
+
function registerBuiltIns(create) {
|
|
5
|
+
create(String, {
|
|
6
|
+
toXML(ctx) {
|
|
7
|
+
return {
|
|
8
|
+
elements: [fromContent(ctx.object, "string")]
|
|
9
|
+
};
|
|
10
|
+
},
|
|
11
|
+
fromXML(ctx) {
|
|
12
|
+
return String(getContent(ctx.xml.elements[0]));
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
create(Number, {
|
|
16
|
+
toXML(ctx) {
|
|
17
|
+
return {
|
|
18
|
+
elements: [fromContent(String(ctx.object), "number")]
|
|
19
|
+
};
|
|
20
|
+
},
|
|
21
|
+
fromXML(ctx) {
|
|
22
|
+
return Number(getContent(ctx.xml.elements[0]));
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
create(Boolean, {
|
|
26
|
+
toXML(ctx) {
|
|
27
|
+
return {
|
|
28
|
+
elements: [
|
|
29
|
+
{
|
|
30
|
+
type: "element",
|
|
31
|
+
name: "boolean",
|
|
32
|
+
...fromContent(String(ctx.object))
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
fromXML(ctx) {
|
|
38
|
+
return Boolean(getContent(ctx.xml.elements[0]));
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
__name(registerBuiltIns, "registerBuiltIns");
|
|
43
|
+
export {
|
|
44
|
+
registerBuiltIns as default
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=built-ins.js.map
|
|
@@ -1,23 +1,19 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { XMLModelOptions, XMLModelPropertyOptions, CreateXMLModelOptions } from
|
|
3
|
-
import { XMLRoot } from
|
|
1
|
+
import { Constructor } from 'typescript-rtti';
|
|
2
|
+
import { XMLModelOptions, XMLModelPropertyOptions, CreateXMLModelOptions } from './types';
|
|
3
|
+
import { XMLRoot } from '../types';
|
|
4
4
|
export declare class XMLModel<T = any> {
|
|
5
5
|
readonly type: Constructor<T>;
|
|
6
6
|
options: XMLModelOptions<T>;
|
|
7
7
|
constructor(type: Constructor<T>, options: CreateXMLModelOptions<T>);
|
|
8
8
|
fromXML(xml: XMLRoot | string): T;
|
|
9
|
-
toXML(instance:
|
|
10
|
-
get reflectedClass(): import(
|
|
9
|
+
toXML(instance: unknown): XMLRoot;
|
|
10
|
+
get reflectedClass(): import('typescript-rtti').ReflectedClass<Constructor<T>>;
|
|
11
11
|
resolveAllProperties(): Map<string, XMLModelPropertyOptions<any> & {
|
|
12
12
|
model: any;
|
|
13
13
|
}>;
|
|
14
14
|
}
|
|
15
15
|
export declare function createModel<T>(type: Constructor<T>, options: CreateXMLModelOptions<T>): XMLModel<T>;
|
|
16
|
-
declare type ModelID<T> = Constructor<T>;
|
|
17
|
-
export declare const Models: Map<ModelID<unknown>, XMLModel<unknown>>;
|
|
18
|
-
export declare function findModel<T>(id: ModelID<T>): XMLModel<T> | undefined;
|
|
19
|
-
export declare function getModel<T>(id: ModelID<T>): XMLModel<T>;
|
|
20
16
|
declare function ModelDecoratorFactory<T>(options?: CreateXMLModelOptions<T>): (constructor: Constructor<T>) => void;
|
|
17
|
+
export { getModel } from './registry';
|
|
21
18
|
export { ModelDecoratorFactory as Model };
|
|
22
|
-
export { Prop } from
|
|
23
|
-
import "../defaults/models";
|
|
19
|
+
export { Prop } from './property';
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
import { reflect } from "typescript-rtti";
|
|
4
|
+
import { ToXMLConversionError, PropertyToXMLConversionError, FromXMLConversionError, PropertyFromXMLConversionError } from "../errors.js";
|
|
5
|
+
import mergeMaps from "../util/merge-maps.js";
|
|
6
|
+
import { resolve, MiddlewareChain } from "../middleware.js";
|
|
7
|
+
import { getPropertyConversionOptions } from "./property.js";
|
|
8
|
+
import { Prop } from "./property.js";
|
|
9
|
+
import XML from "../xml/index.js";
|
|
10
|
+
import { defaults } from "../defaults.js";
|
|
11
|
+
import { findModel, registrerModel } from "./registry.js";
|
|
12
|
+
import { getModel } from "./registry.js";
|
|
13
|
+
import registerBuiltIns from "./built-ins.js";
|
|
14
|
+
function* ParentChain(constructor) {
|
|
15
|
+
let parent = Object.getPrototypeOf(constructor);
|
|
16
|
+
if (parent === constructor) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
while (parent) {
|
|
20
|
+
yield parent;
|
|
21
|
+
const _parent = Object.getPrototypeOf(constructor);
|
|
22
|
+
if (parent === _parent) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
parent = _parent;
|
|
26
|
+
}
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
__name(ParentChain, "ParentChain");
|
|
30
|
+
function getParentModel(model) {
|
|
31
|
+
if (model.options.parent)
|
|
32
|
+
return model.options.parent;
|
|
33
|
+
for (const constructor of ParentChain(model.type)) {
|
|
34
|
+
const model2 = findModel(constructor);
|
|
35
|
+
if (model2) {
|
|
36
|
+
return model2;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
__name(getParentModel, "getParentModel");
|
|
42
|
+
const _XMLModel = class _XMLModel {
|
|
43
|
+
constructor(type, options) {
|
|
44
|
+
this.type = type;
|
|
45
|
+
const model = this;
|
|
46
|
+
let parent = void 0;
|
|
47
|
+
const getParent = /* @__PURE__ */ __name(() => {
|
|
48
|
+
if (typeof parent === "undefined")
|
|
49
|
+
parent = getParentModel(this);
|
|
50
|
+
return parent;
|
|
51
|
+
}, "getParent");
|
|
52
|
+
let propertiesLoaded = false;
|
|
53
|
+
const properties = {
|
|
54
|
+
options: /* @__PURE__ */ new Map(),
|
|
55
|
+
fromXML: {
|
|
56
|
+
get parent() {
|
|
57
|
+
return getParent()?.options.properties.fromXML || null;
|
|
58
|
+
},
|
|
59
|
+
middlewares: [
|
|
60
|
+
(context, next) => {
|
|
61
|
+
const record = getParent() ? next() : {};
|
|
62
|
+
properties.options.forEach((property) => {
|
|
63
|
+
const xml = context.xml;
|
|
64
|
+
const elements = property.resolveElements({
|
|
65
|
+
model,
|
|
66
|
+
xml,
|
|
67
|
+
property
|
|
68
|
+
});
|
|
69
|
+
const propertyFromXMLContext = {
|
|
70
|
+
model,
|
|
71
|
+
xml: context.xml,
|
|
72
|
+
property,
|
|
73
|
+
elements
|
|
74
|
+
};
|
|
75
|
+
try {
|
|
76
|
+
record[property.name] = property.fromXML(propertyFromXMLContext);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
if (error instanceof FromXMLConversionError) {
|
|
79
|
+
throw error;
|
|
80
|
+
} else {
|
|
81
|
+
throw new PropertyFromXMLConversionError(context, propertyFromXMLContext, error);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
return record;
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
},
|
|
89
|
+
toXML: {
|
|
90
|
+
get parent() {
|
|
91
|
+
return getParent()?.options.properties.toXML || null;
|
|
92
|
+
},
|
|
93
|
+
middlewares: [
|
|
94
|
+
(context, next) => {
|
|
95
|
+
const record = getParent() ? next() : {};
|
|
96
|
+
properties.options.forEach((options2) => {
|
|
97
|
+
const propertyToXMLContext = {
|
|
98
|
+
model,
|
|
99
|
+
object: context.object,
|
|
100
|
+
property: options2,
|
|
101
|
+
value: context.object[options2.name]
|
|
102
|
+
};
|
|
103
|
+
try {
|
|
104
|
+
record[options2.name] = options2.toXML(propertyToXMLContext);
|
|
105
|
+
} catch (error) {
|
|
106
|
+
if (error instanceof ToXMLConversionError) {
|
|
107
|
+
throw error;
|
|
108
|
+
} else {
|
|
109
|
+
throw new PropertyToXMLConversionError(context, propertyToXMLContext, error);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
return record;
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
const loadProperties = /* @__PURE__ */ __name(() => {
|
|
119
|
+
const props = this.reflectedClass.ownProperties.filter((prop) => typeof prop.host.constructor.prototype[prop.name] !== "function");
|
|
120
|
+
props.forEach((property) => {
|
|
121
|
+
const options2 = getPropertyConversionOptions(this.type, property.name);
|
|
122
|
+
if (!options2.ignored) {
|
|
123
|
+
properties.options.set(property.name, options2);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
propertiesLoaded = true;
|
|
127
|
+
}, "loadProperties");
|
|
128
|
+
this.options = {
|
|
129
|
+
get properties() {
|
|
130
|
+
if (!propertiesLoaded)
|
|
131
|
+
loadProperties();
|
|
132
|
+
return properties;
|
|
133
|
+
},
|
|
134
|
+
fromXML: {
|
|
135
|
+
middlewares: [],
|
|
136
|
+
get parent() {
|
|
137
|
+
return getParent()?.options.fromXML || null;
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
toXML: {
|
|
141
|
+
middlewares: [],
|
|
142
|
+
get parent() {
|
|
143
|
+
return getParent()?.options.toXML || null;
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
get tagname() {
|
|
147
|
+
return options.tagname || defaults.tagnameFromModel(model);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
if (options.parent)
|
|
151
|
+
this.options.parent = options.parent;
|
|
152
|
+
if (!getParent()) {
|
|
153
|
+
this.options.fromXML.middlewares.push((ctx) => defaults.fromXML(ctx));
|
|
154
|
+
this.options.toXML.middlewares.push((ctx) => defaults.toXML(ctx));
|
|
155
|
+
}
|
|
156
|
+
if (options.fromXML)
|
|
157
|
+
this.options.fromXML.middlewares.push(options.fromXML);
|
|
158
|
+
if (options.toXML)
|
|
159
|
+
this.options.toXML.middlewares.push(options.toXML);
|
|
160
|
+
}
|
|
161
|
+
fromXML(xml) {
|
|
162
|
+
const _xml = typeof xml === "string" ? XML.parse(xml) : xml;
|
|
163
|
+
const model = this;
|
|
164
|
+
const context = {
|
|
165
|
+
xml: _xml,
|
|
166
|
+
get properties() {
|
|
167
|
+
const propContext = {
|
|
168
|
+
xml: _xml,
|
|
169
|
+
model
|
|
170
|
+
};
|
|
171
|
+
return resolve(MiddlewareChain(model.options.properties.fromXML), propContext);
|
|
172
|
+
},
|
|
173
|
+
model
|
|
174
|
+
};
|
|
175
|
+
return resolve(MiddlewareChain(this.options.fromXML), context);
|
|
176
|
+
}
|
|
177
|
+
toXML(instance) {
|
|
178
|
+
const model = this;
|
|
179
|
+
if (instance instanceof this.type || typeof instance !== "undefined" && instance.constructor === this.type) {
|
|
180
|
+
const context = {
|
|
181
|
+
object: instance,
|
|
182
|
+
get properties() {
|
|
183
|
+
const propContext = {
|
|
184
|
+
object: instance,
|
|
185
|
+
model
|
|
186
|
+
};
|
|
187
|
+
return resolve(MiddlewareChain(model.options.properties.toXML), propContext);
|
|
188
|
+
},
|
|
189
|
+
model: this
|
|
190
|
+
};
|
|
191
|
+
return resolve(MiddlewareChain(this.options.toXML), context);
|
|
192
|
+
} else {
|
|
193
|
+
throw new TypeError(`provided object is not an instance of ${this.type.name}`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
get reflectedClass() {
|
|
197
|
+
return reflect(this.type);
|
|
198
|
+
}
|
|
199
|
+
resolveAllProperties() {
|
|
200
|
+
const ownProperties = /* @__PURE__ */ new Map();
|
|
201
|
+
const parent = getParentModel(this);
|
|
202
|
+
this.options.properties.options.forEach((options, key) => {
|
|
203
|
+
ownProperties.set(key, new Proxy(options, {
|
|
204
|
+
get: /* @__PURE__ */ __name((target, p, reciever) => {
|
|
205
|
+
if (p === "model")
|
|
206
|
+
return this;
|
|
207
|
+
else
|
|
208
|
+
return Reflect.get(target, p, reciever);
|
|
209
|
+
}, "get")
|
|
210
|
+
}));
|
|
211
|
+
});
|
|
212
|
+
const res = parent ? mergeMaps(parent.resolveAllProperties(), ownProperties) : ownProperties;
|
|
213
|
+
return res;
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
__name(_XMLModel, "XMLModel");
|
|
217
|
+
let XMLModel = _XMLModel;
|
|
218
|
+
function createModel(type, options) {
|
|
219
|
+
if (findModel(type)) {
|
|
220
|
+
throw new TypeError(`a model for type ${type.name} already exists`);
|
|
221
|
+
}
|
|
222
|
+
const model = new XMLModel(type, options);
|
|
223
|
+
registrerModel(model);
|
|
224
|
+
return model;
|
|
225
|
+
}
|
|
226
|
+
__name(createModel, "createModel");
|
|
227
|
+
function ModelDecoratorFactory(options) {
|
|
228
|
+
return function(constructor) {
|
|
229
|
+
if (!findModel(constructor))
|
|
230
|
+
createModel(constructor, options || {});
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
__name(ModelDecoratorFactory, "ModelDecoratorFactory");
|
|
234
|
+
registerBuiltIns(createModel);
|
|
235
|
+
export {
|
|
236
|
+
ModelDecoratorFactory as Model,
|
|
237
|
+
Prop,
|
|
238
|
+
XMLModel,
|
|
239
|
+
createModel,
|
|
240
|
+
getModel
|
|
241
|
+
};
|
|
242
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { Constructor } from 'typescript-rtti';
|
|
2
|
+
import { XMLModelProperty, XMLModelPropertyOptions, CreateXMLModelPropertyOptions } from './types';
|
|
3
3
|
export declare function getPropertyConversionOptions<T>(constructor: Constructor<T>, property: XMLModelProperty<T>): XMLModelPropertyOptions<T>;
|
|
4
4
|
declare function PropDecoratorFactory<T = any>(options?: CreateXMLModelPropertyOptions<T>): (prototype: any, property: XMLModelProperty<T>) => void;
|
|
5
5
|
export { PropDecoratorFactory as Prop };
|