xml-model 0.1.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/.eslintignore +3 -0
- package/.eslintrc.js +6 -0
- package/.gitignore +2 -0
- package/.vscode/launch.json +21 -0
- package/.vscode/settings.json +3 -0
- package/README.md +7 -0
- package/build/main/defaults/index.d.ts +14 -0
- package/build/main/defaults/index.js +165 -0
- package/build/main/defaults/models.d.ts +1 -0
- package/build/main/defaults/models.js +55 -0
- package/build/main/index.d.ts +5 -0
- package/build/main/index.js +31 -0
- package/build/main/middleware.d.ts +9 -0
- package/build/main/middleware.js +65 -0
- package/build/main/model/index.d.ts +26 -0
- package/build/main/model/index.js +304 -0
- package/build/main/model/property.d.ts +5 -0
- package/build/main/model/property.js +95 -0
- package/build/main/model/types.d.ts +69 -0
- package/build/main/model/types.js +214 -0
- package/build/main/model.spec.d.ts +1 -0
- package/build/main/model.spec.js +261 -0
- package/build/main/types.d.ts +8 -0
- package/build/main/types.js +18 -0
- package/build/main/xml.d.ts +31 -0
- package/build/main/xml.js +95 -0
- package/build/module/defaults/index.d.ts +13 -0
- package/build/module/defaults/index.js +71 -0
- package/build/module/defaults/models.d.ts +1 -0
- package/build/module/defaults/models.js +27 -0
- package/build/module/errors.d.ts +3 -0
- package/build/module/errors.js +37 -0
- package/build/module/index.d.ts +4 -0
- package/build/module/index.js +19 -0
- package/build/module/middleware.d.ts +9 -0
- package/build/module/middleware.js +60 -0
- package/build/module/model.d.ts +71 -0
- package/build/module/model.js +466 -0
- package/build/module/model.spec.d.ts +1 -0
- package/build/module/model.spec.js +76 -0
- package/build/module/types.d.ts +13 -0
- package/build/module/types.js +40 -0
- package/build/module/xml-from-object.d.ts +11 -0
- package/build/module/xml-from-object.js +58 -0
- package/build/module/xml-from-object.spec.d.ts +1 -0
- package/build/module/xml-from-object.spec.js +104 -0
- package/build/module/xml-to-object.d.ts +11 -0
- package/build/module/xml-to-object.js +55 -0
- package/build/module/xml.d.ts +15 -0
- package/build/module/xml.js +74 -0
- package/package.json +50 -0
- package/register-ts-node.js +9 -0
- package/src/defaults/index.ts +181 -0
- package/src/defaults/models.ts +45 -0
- package/src/index.ts +6 -0
- package/src/middleware.ts +34 -0
- package/src/model/index.ts +245 -0
- package/src/model/property.ts +104 -0
- package/src/model/types.ts +99 -0
- package/src/model.spec.ts +178 -0
- package/src/types.ts +8 -0
- package/src/xml.ts +80 -0
- package/tsconfig.json +106 -0
- package/tsconfig.module.json +9 -0
- package/yarn.lock +2217 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const __RΦ = { m: (k, v) => (t, ...a) => t && Reflect.metadata ? Reflect.metadata(k, v)(t, ...a) : void 0, f: (f, d, n) => (d.forEach(d => d(f)), Object.defineProperty(f, "name", { value: n, writable: false }), f), c: (c, d, dp, dsp, n) => (d.forEach(d => d(c)), dp.forEach(([p, d]) => d(c.prototype, p)), dsp.forEach(([p, d]) => d(c, p)), n ? Object.defineProperty(c, "name", { value: n, writable: false }) : undefined, c), r: (o, a) => (Object.assign(o, a)), a: id => {
|
|
2
|
+
let t = __RΦ.t[id];
|
|
3
|
+
if (t === void 0)
|
|
4
|
+
return void 0;
|
|
5
|
+
if (t.RΦ) {
|
|
6
|
+
let r = t.RΦ;
|
|
7
|
+
delete t.RΦ;
|
|
8
|
+
__RΦ.r(t, r(t));
|
|
9
|
+
}
|
|
10
|
+
else if (t.LΦ) {
|
|
11
|
+
let l = t.LΦ();
|
|
12
|
+
delete t.LΦ;
|
|
13
|
+
__RΦ.t[id] = t = l;
|
|
14
|
+
}
|
|
15
|
+
return t;
|
|
16
|
+
}, t: { [384]: { LΦ: t => LΦ_0.IΦElement }, [28]: { LΦ: t => Object }, [610]: { RΦ: t => ({ TΦ: "|", t: [__RΦ.a(12), __RΦ.a(609)] }) }, [12]: { RΦ: t => ({ TΦ: "n" }) }, [609]: { TΦ: "5", name: "XMLFromObjectOptions" }, [612]: { RΦ: t => ({ TΦ: "[", e: __RΦ.a(611) }) }, [611]: { RΦ: t => ({ TΦ: "O", m: [{ n: "__call", f: "", t: __RΦ.a(4) }] }) }, [4]: { RΦ: t => ({ TΦ: "~" }) } } };
|
|
17
|
+
import { MiddlewareChain, resolve } from "./middleware";
|
|
18
|
+
import * as LΦ_0 from "./types";
|
|
19
|
+
var IΦXMLFromObjectMiddlewareContext = { name: "XMLFromObjectMiddlewareContext", prototype: {}, identity: Symbol("XMLFromObjectMiddlewareContext (interface)") };
|
|
20
|
+
export { IΦXMLFromObjectMiddlewareContext };
|
|
21
|
+
(t => __RΦ.t[608] = t)(IΦXMLFromObjectMiddlewareContext);
|
|
22
|
+
__RΦ.m("rt:P", ["xml", "object"])(IΦXMLFromObjectMiddlewareContext);
|
|
23
|
+
__RΦ.m("rt:m", [])(IΦXMLFromObjectMiddlewareContext);
|
|
24
|
+
__RΦ.m("rt:f", "Ie")(IΦXMLFromObjectMiddlewareContext);
|
|
25
|
+
__RΦ.m("rt:t", () => __RΦ.a(384))(IΦXMLFromObjectMiddlewareContext.prototype, "xml");
|
|
26
|
+
__RΦ.m("rt:f", "P")(IΦXMLFromObjectMiddlewareContext.prototype, "xml");
|
|
27
|
+
__RΦ.m("rt:t", () => __RΦ.a(28))(IΦXMLFromObjectMiddlewareContext.prototype, "object");
|
|
28
|
+
__RΦ.m("rt:f", "P")(IΦXMLFromObjectMiddlewareContext.prototype, "object");
|
|
29
|
+
__RΦ.m("rt:t", () => __RΦ.a(384))(IΦXMLFromObjectMiddlewareContext.prototype, "xml");
|
|
30
|
+
__RΦ.m("rt:f", "P")(IΦXMLFromObjectMiddlewareContext.prototype, "xml");
|
|
31
|
+
__RΦ.m("rt:t", () => __RΦ.a(28))(IΦXMLFromObjectMiddlewareContext.prototype, "object");
|
|
32
|
+
__RΦ.m("rt:f", "P")(IΦXMLFromObjectMiddlewareContext.prototype, "object");
|
|
33
|
+
var IΦXMLFromObjectOptions = { name: "XMLFromObjectOptions", prototype: {}, identity: Symbol("XMLFromObjectOptions (interface)") };
|
|
34
|
+
export { IΦXMLFromObjectOptions };
|
|
35
|
+
(t => __RΦ.t[609] = t)(IΦXMLFromObjectOptions);
|
|
36
|
+
__RΦ.m("rt:P", ["parent", "middlewares"])(IΦXMLFromObjectOptions);
|
|
37
|
+
__RΦ.m("rt:m", [])(IΦXMLFromObjectOptions);
|
|
38
|
+
__RΦ.m("rt:f", "Ie")(IΦXMLFromObjectOptions);
|
|
39
|
+
__RΦ.m("rt:t", () => __RΦ.a(610))(IΦXMLFromObjectOptions.prototype, "parent");
|
|
40
|
+
__RΦ.m("rt:f", "P")(IΦXMLFromObjectOptions.prototype, "parent");
|
|
41
|
+
__RΦ.m("rt:t", () => __RΦ.a(612))(IΦXMLFromObjectOptions.prototype, "middlewares");
|
|
42
|
+
__RΦ.m("rt:f", "P")(IΦXMLFromObjectOptions.prototype, "middlewares");
|
|
43
|
+
__RΦ.m("rt:t", () => __RΦ.a(610))(IΦXMLFromObjectOptions.prototype, "parent");
|
|
44
|
+
__RΦ.m("rt:f", "P")(IΦXMLFromObjectOptions.prototype, "parent");
|
|
45
|
+
__RΦ.m("rt:t", () => __RΦ.a(612))(IΦXMLFromObjectOptions.prototype, "middlewares");
|
|
46
|
+
__RΦ.m("rt:f", "P")(IΦXMLFromObjectOptions.prototype, "middlewares");
|
|
47
|
+
export function xmlFromObject(object, options) {
|
|
48
|
+
const middlewares = MiddlewareChain(options);
|
|
49
|
+
const context = {
|
|
50
|
+
xml: { type: "element" },
|
|
51
|
+
object,
|
|
52
|
+
};
|
|
53
|
+
resolve(middlewares, context);
|
|
54
|
+
return context.xml;
|
|
55
|
+
}
|
|
56
|
+
__RΦ.m("rt:p", [{ n: "object", t: () => __RΦ.a(28), v: null }, { n: "options", t: () => __RΦ.a(609), v: null }])(xmlFromObject);
|
|
57
|
+
__RΦ.m("rt:f", "F")(xmlFromObject);
|
|
58
|
+
__RΦ.m("rt:t", () => __RΦ.a(384))(xmlFromObject);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "mocha";
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
const __RΦ = { m: (k, v) => (t, ...a) => t && Reflect.metadata ? Reflect.metadata(k, v)(t, ...a) : void 0, f: (f, d, n) => (d.forEach(d => d(f)), Object.defineProperty(f, "name", { value: n, writable: false }), f), c: (c, d, dp, dsp, n) => (d.forEach(d => d(c)), dp.forEach(([p, d]) => d(c.prototype, p)), dsp.forEach(([p, d]) => d(c, p)), n ? Object.defineProperty(c, "name", { value: n, writable: false }) : undefined, c), r: (o, a) => (Object.assign(o, a)), a: id => {
|
|
8
|
+
let t = __RΦ.t[id];
|
|
9
|
+
if (t === void 0)
|
|
10
|
+
return void 0;
|
|
11
|
+
if (t.RΦ) {
|
|
12
|
+
let r = t.RΦ;
|
|
13
|
+
delete t.RΦ;
|
|
14
|
+
__RΦ.r(t, r(t));
|
|
15
|
+
}
|
|
16
|
+
else if (t.LΦ) {
|
|
17
|
+
let l = t.LΦ();
|
|
18
|
+
delete t.LΦ;
|
|
19
|
+
__RΦ.t[id] = t = l;
|
|
20
|
+
}
|
|
21
|
+
return t;
|
|
22
|
+
}, t: { [1657]: { RΦ: t => ({ TΦ: "O", m: [{ n: "name", f: "", t: __RΦ.a(13) }, { n: "nbPages", f: "", t: __RΦ.a(14) }] }) }, [13]: { LΦ: t => String }, [14]: { LΦ: t => Number }, [1664]: { RΦ: t => ({ TΦ: "[", e: __RΦ.a(1652) }) }, [1652]: { TΦ: "5", name: "Book" }, [4]: { RΦ: t => ({ TΦ: "~" }) }, [22]: { RΦ: t => ({ TΦ: "V" }) } } };
|
|
23
|
+
import "mocha";
|
|
24
|
+
import { expect } from "chai";
|
|
25
|
+
import { Model, Prop, getModel } from "./model";
|
|
26
|
+
import { js2xml } from "xml-js";
|
|
27
|
+
let Book = class Book {
|
|
28
|
+
name;
|
|
29
|
+
nbPages;
|
|
30
|
+
constructor(options) {
|
|
31
|
+
this.name = options.name;
|
|
32
|
+
this.nbPages = options.nbPages;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
__decorate([
|
|
36
|
+
Prop()
|
|
37
|
+
], Book.prototype, "name", void 0);
|
|
38
|
+
__decorate([
|
|
39
|
+
Prop()
|
|
40
|
+
], Book.prototype, "nbPages", void 0);
|
|
41
|
+
Book = __decorate([
|
|
42
|
+
Model()
|
|
43
|
+
], Book);
|
|
44
|
+
(t => __RΦ.t[1652] = t)(Book);
|
|
45
|
+
__RΦ.m("rt:SP", [])(Book);
|
|
46
|
+
__RΦ.m("rt:P", ["name", "nbPages"])(Book);
|
|
47
|
+
__RΦ.m("rt:Sm", [])(Book);
|
|
48
|
+
__RΦ.m("rt:m", [])(Book);
|
|
49
|
+
__RΦ.m("rt:p", [{ n: "options", t: () => __RΦ.a(1657), v: null }])(Book);
|
|
50
|
+
__RΦ.m("rt:f", "C")(Book);
|
|
51
|
+
__RΦ.m("rt:t", () => __RΦ.a(13))(Book.prototype, "name");
|
|
52
|
+
__RΦ.m("rt:f", "P")(Book.prototype, "name");
|
|
53
|
+
__RΦ.m("rt:t", () => __RΦ.a(14))(Book.prototype, "nbPages");
|
|
54
|
+
__RΦ.m("rt:f", "P")(Book.prototype, "nbPages");
|
|
55
|
+
let Library = class Library {
|
|
56
|
+
name;
|
|
57
|
+
books = [];
|
|
58
|
+
constructor(name) {
|
|
59
|
+
this.name = name;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
__decorate([
|
|
63
|
+
Prop()
|
|
64
|
+
], Library.prototype, "name", void 0);
|
|
65
|
+
__decorate([
|
|
66
|
+
Prop()
|
|
67
|
+
], Library.prototype, "books", void 0);
|
|
68
|
+
Library = __decorate([
|
|
69
|
+
Model()
|
|
70
|
+
], Library);
|
|
71
|
+
(t => __RΦ.t[1659] = t)(Library);
|
|
72
|
+
__RΦ.m("rt:SP", [])(Library);
|
|
73
|
+
__RΦ.m("rt:P", ["name", "books"])(Library);
|
|
74
|
+
__RΦ.m("rt:Sm", [])(Library);
|
|
75
|
+
__RΦ.m("rt:m", [])(Library);
|
|
76
|
+
__RΦ.m("rt:p", [{ n: "name", t: () => __RΦ.a(13), v: null }])(Library);
|
|
77
|
+
__RΦ.m("rt:f", "C")(Library);
|
|
78
|
+
__RΦ.m("rt:t", () => __RΦ.a(13))(Library.prototype, "name");
|
|
79
|
+
__RΦ.m("rt:f", "P")(Library.prototype, "name");
|
|
80
|
+
__RΦ.m("rt:t", () => __RΦ.a(1664))(Library.prototype, "books");
|
|
81
|
+
__RΦ.m("rt:f", "P")(Library.prototype, "books");
|
|
82
|
+
describe("XML from Object", __RΦ.f(() => {
|
|
83
|
+
it("should convert to XML as expected", __RΦ.f(() => {
|
|
84
|
+
const library = new Library("test");
|
|
85
|
+
for (let i = 1; i <= 4; i++) {
|
|
86
|
+
const book = new Book({ name: `Book #${i}`, nbPages: Math.pow(10, i) });
|
|
87
|
+
library.books.push(book);
|
|
88
|
+
}
|
|
89
|
+
const xml = getModel(Library).toXMLElement(library);
|
|
90
|
+
const expectedXMLString = `<library>
|
|
91
|
+
<name>${library.name}</name>
|
|
92
|
+
<books>
|
|
93
|
+
${library.books
|
|
94
|
+
.map(__RΦ.f((book) => ` <book>
|
|
95
|
+
<name>${book.name}</name>
|
|
96
|
+
<nb-pages>${book.nbPages}</nb-pages>
|
|
97
|
+
</book>`, [__RΦ.m("rt:p", [{ n: "book", t: () => __RΦ.a(4), v: null }]), __RΦ.m("rt:f", "F>"), __RΦ.m("rt:t", () => __RΦ.a(13))], ""))
|
|
98
|
+
.join("")}
|
|
99
|
+
</books>
|
|
100
|
+
</library>`.replace(/>(\ |\n)*</g, "><");
|
|
101
|
+
const xmlString = js2xml({ elements: [xml] });
|
|
102
|
+
expect(xmlString).to.equal(expectedXMLString);
|
|
103
|
+
}, [__RΦ.m("rt:p", []), __RΦ.m("rt:f", "F>"), __RΦ.m("rt:t", () => __RΦ.a(22))], ""));
|
|
104
|
+
}, [__RΦ.m("rt:p", []), __RΦ.m("rt:f", "F>"), __RΦ.m("rt:t", () => __RΦ.a(22))], ""));
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { XMLElement, UnknownRecord } from "./types";
|
|
2
|
+
import { Middleware } from "./middleware";
|
|
3
|
+
export interface XMLToObjectMiddlewareContext {
|
|
4
|
+
xml: XMLElement;
|
|
5
|
+
record: UnknownRecord;
|
|
6
|
+
}
|
|
7
|
+
export interface XMLToObjectOptions {
|
|
8
|
+
parent: XMLToObjectOptions | null;
|
|
9
|
+
middlewares: Middleware<XMLToObjectMiddlewareContext, void>[];
|
|
10
|
+
}
|
|
11
|
+
export declare function xmlToObject(xml: XMLElement, options: XMLToObjectOptions): UnknownRecord;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const __RΦ = { m: (k, v) => (t, ...a) => t && Reflect.metadata ? Reflect.metadata(k, v)(t, ...a) : void 0, f: (f, d, n) => (d.forEach(d => d(f)), Object.defineProperty(f, "name", { value: n, writable: false }), f), c: (c, d, dp, dsp, n) => (d.forEach(d => d(c)), dp.forEach(([p, d]) => d(c.prototype, p)), dsp.forEach(([p, d]) => d(c, p)), n ? Object.defineProperty(c, "name", { value: n, writable: false }) : undefined, c), r: (o, a) => (Object.assign(o, a)), a: id => {
|
|
2
|
+
let t = __RΦ.t[id];
|
|
3
|
+
if (t === void 0)
|
|
4
|
+
return void 0;
|
|
5
|
+
if (t.RΦ) {
|
|
6
|
+
let r = t.RΦ;
|
|
7
|
+
delete t.RΦ;
|
|
8
|
+
__RΦ.r(t, r(t));
|
|
9
|
+
}
|
|
10
|
+
else if (t.LΦ) {
|
|
11
|
+
let l = t.LΦ();
|
|
12
|
+
delete t.LΦ;
|
|
13
|
+
__RΦ.t[id] = t = l;
|
|
14
|
+
}
|
|
15
|
+
return t;
|
|
16
|
+
}, t: { [384]: { LΦ: t => LΦ_0.IΦElement }, [113]: { RΦ: t => ({ TΦ: "m", t: __RΦ.a(114), p: [] }) }, [114]: { LΦ: t => Object }, [386]: { RΦ: t => ({ TΦ: "|", t: [__RΦ.a(12), __RΦ.a(385)] }) }, [12]: { RΦ: t => ({ TΦ: "n" }) }, [385]: { TΦ: "5", name: "XMLToObjectOptions" }, [388]: { RΦ: t => ({ TΦ: "[", e: __RΦ.a(387) }) }, [387]: { RΦ: t => ({ TΦ: "O", m: [{ n: "__call", f: "", t: __RΦ.a(4) }] }) }, [4]: { RΦ: t => ({ TΦ: "~" }) } } };
|
|
17
|
+
import { MiddlewareChain, resolve } from "./middleware";
|
|
18
|
+
import * as LΦ_0 from "./types";
|
|
19
|
+
var IΦXMLToObjectMiddlewareContext = { name: "XMLToObjectMiddlewareContext", prototype: {}, identity: Symbol("XMLToObjectMiddlewareContext (interface)") };
|
|
20
|
+
export { IΦXMLToObjectMiddlewareContext };
|
|
21
|
+
(t => __RΦ.t[383] = t)(IΦXMLToObjectMiddlewareContext);
|
|
22
|
+
__RΦ.m("rt:P", ["xml", "record"])(IΦXMLToObjectMiddlewareContext);
|
|
23
|
+
__RΦ.m("rt:m", [])(IΦXMLToObjectMiddlewareContext);
|
|
24
|
+
__RΦ.m("rt:f", "Ie")(IΦXMLToObjectMiddlewareContext);
|
|
25
|
+
__RΦ.m("rt:t", () => __RΦ.a(384))(IΦXMLToObjectMiddlewareContext.prototype, "xml");
|
|
26
|
+
__RΦ.m("rt:f", "P")(IΦXMLToObjectMiddlewareContext.prototype, "xml");
|
|
27
|
+
__RΦ.m("rt:t", () => __RΦ.a(113))(IΦXMLToObjectMiddlewareContext.prototype, "record");
|
|
28
|
+
__RΦ.m("rt:f", "P")(IΦXMLToObjectMiddlewareContext.prototype, "record");
|
|
29
|
+
__RΦ.m("rt:t", () => __RΦ.a(384))(IΦXMLToObjectMiddlewareContext.prototype, "xml");
|
|
30
|
+
__RΦ.m("rt:f", "P")(IΦXMLToObjectMiddlewareContext.prototype, "xml");
|
|
31
|
+
__RΦ.m("rt:t", () => __RΦ.a(113))(IΦXMLToObjectMiddlewareContext.prototype, "record");
|
|
32
|
+
__RΦ.m("rt:f", "P")(IΦXMLToObjectMiddlewareContext.prototype, "record");
|
|
33
|
+
var IΦXMLToObjectOptions = { name: "XMLToObjectOptions", prototype: {}, identity: Symbol("XMLToObjectOptions (interface)") };
|
|
34
|
+
export { IΦXMLToObjectOptions };
|
|
35
|
+
(t => __RΦ.t[385] = t)(IΦXMLToObjectOptions);
|
|
36
|
+
__RΦ.m("rt:P", ["parent", "middlewares"])(IΦXMLToObjectOptions);
|
|
37
|
+
__RΦ.m("rt:m", [])(IΦXMLToObjectOptions);
|
|
38
|
+
__RΦ.m("rt:f", "Ie")(IΦXMLToObjectOptions);
|
|
39
|
+
__RΦ.m("rt:t", () => __RΦ.a(386))(IΦXMLToObjectOptions.prototype, "parent");
|
|
40
|
+
__RΦ.m("rt:f", "P")(IΦXMLToObjectOptions.prototype, "parent");
|
|
41
|
+
__RΦ.m("rt:t", () => __RΦ.a(388))(IΦXMLToObjectOptions.prototype, "middlewares");
|
|
42
|
+
__RΦ.m("rt:f", "P")(IΦXMLToObjectOptions.prototype, "middlewares");
|
|
43
|
+
__RΦ.m("rt:t", () => __RΦ.a(386))(IΦXMLToObjectOptions.prototype, "parent");
|
|
44
|
+
__RΦ.m("rt:f", "P")(IΦXMLToObjectOptions.prototype, "parent");
|
|
45
|
+
__RΦ.m("rt:t", () => __RΦ.a(388))(IΦXMLToObjectOptions.prototype, "middlewares");
|
|
46
|
+
__RΦ.m("rt:f", "P")(IΦXMLToObjectOptions.prototype, "middlewares");
|
|
47
|
+
export function xmlToObject(xml, options) {
|
|
48
|
+
const record = {};
|
|
49
|
+
const middlewares = MiddlewareChain(options);
|
|
50
|
+
resolve(middlewares, { xml, record });
|
|
51
|
+
return record;
|
|
52
|
+
}
|
|
53
|
+
__RΦ.m("rt:p", [{ n: "xml", t: () => __RΦ.a(384), v: null }, { n: "options", t: () => __RΦ.a(385), v: null }])(xmlToObject);
|
|
54
|
+
__RΦ.m("rt:f", "F")(xmlToObject);
|
|
55
|
+
__RΦ.m("rt:t", () => __RΦ.a(113))(xmlToObject);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { js2xml } from "xml-js";
|
|
2
|
+
import { XMLElement } from "./types";
|
|
3
|
+
export declare function parse(string: string): XMLElement | import("xml-js").ElementCompact;
|
|
4
|
+
export declare function stringify(xml: XMLElement, options: Parameters<typeof js2xml>[1]): string;
|
|
5
|
+
export declare function getContent(xml: XMLElement): string | number | boolean | undefined;
|
|
6
|
+
export declare function fromContent(content?: string, tag?: string, attributes?: XMLElement["attributes"]): XMLElement;
|
|
7
|
+
export declare function addElement(xml: XMLElement, element: XMLElement): void;
|
|
8
|
+
declare const XML: {
|
|
9
|
+
parse: typeof parse;
|
|
10
|
+
stringify: typeof stringify;
|
|
11
|
+
fromContent: typeof fromContent;
|
|
12
|
+
getContent: typeof getContent;
|
|
13
|
+
addElement: typeof addElement;
|
|
14
|
+
};
|
|
15
|
+
export default XML;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const __RΦ = { m: (k, v) => (t, ...a) => t && Reflect.metadata ? Reflect.metadata(k, v)(t, ...a) : void 0, f: (f, d, n) => (d.forEach(d => d(f)), Object.defineProperty(f, "name", { value: n, writable: false }), f), c: (c, d, dp, dsp, n) => (d.forEach(d => d(c)), dp.forEach(([p, d]) => d(c.prototype, p)), dsp.forEach(([p, d]) => d(c, p)), n ? Object.defineProperty(c, "name", { value: n, writable: false }) : undefined, c), r: (o, a) => (Object.assign(o, a)), a: id => {
|
|
2
|
+
let t = __RΦ.t[id];
|
|
3
|
+
if (t === void 0)
|
|
4
|
+
return void 0;
|
|
5
|
+
if (t.RΦ) {
|
|
6
|
+
let r = t.RΦ;
|
|
7
|
+
delete t.RΦ;
|
|
8
|
+
__RΦ.r(t, r(t));
|
|
9
|
+
}
|
|
10
|
+
else if (t.LΦ) {
|
|
11
|
+
let l = t.LΦ();
|
|
12
|
+
delete t.LΦ;
|
|
13
|
+
__RΦ.t[id] = t = l;
|
|
14
|
+
}
|
|
15
|
+
return t;
|
|
16
|
+
}, t: { [13]: { LΦ: t => String }, [639]: { RΦ: t => ({ TΦ: "|", t: [__RΦ.a(384), __RΦ.a(638)] }) }, [384]: { LΦ: t => LΦ_0.IΦElement }, [638]: { LΦ: t => LΦ_0.IΦElementCompact }, [650]: { RΦ: t => ({ TΦ: "|", t: [__RΦ.a(10), __RΦ.a(647)] }) }, [10]: { RΦ: t => ({ TΦ: "u" }) }, [647]: { LΦ: t => LΦ_0.IΦJS2XML }, [679]: { RΦ: t => ({ TΦ: "|", t: [__RΦ.a(10), __RΦ.a(13), __RΦ.a(14), __RΦ.a(17), __RΦ.a(19)] }) }, [14]: { LΦ: t => Number }, [17]: { RΦ: t => ({ TΦ: "0" }) }, [19]: { RΦ: t => ({ TΦ: "1" }) }, [46]: { LΦ: t => "" }, [687]: { RΦ: t => ({ TΦ: "|", t: [__RΦ.a(10), __RΦ.a(686)] }) }, [686]: { LΦ: t => LΦ_0.IΦAttributes }, [22]: { RΦ: t => ({ TΦ: "V" }) } } };
|
|
17
|
+
import { xml2js, js2xml } from "xml-js";
|
|
18
|
+
import * as LΦ_0 from "xml-js/types";
|
|
19
|
+
export function parse(string) {
|
|
20
|
+
return xml2js(string);
|
|
21
|
+
}
|
|
22
|
+
__RΦ.m("rt:p", [{ n: "string", t: () => __RΦ.a(13), v: null }])(parse);
|
|
23
|
+
__RΦ.m("rt:f", "F")(parse);
|
|
24
|
+
__RΦ.m("rt:t", () => __RΦ.a(639))(parse);
|
|
25
|
+
export function stringify(xml, options) {
|
|
26
|
+
return js2xml(xml, options);
|
|
27
|
+
}
|
|
28
|
+
__RΦ.m("rt:p", [{ n: "xml", t: () => __RΦ.a(384), v: null }, { n: "options", t: () => __RΦ.a(650), v: null }])(stringify);
|
|
29
|
+
__RΦ.m("rt:f", "F")(stringify);
|
|
30
|
+
__RΦ.m("rt:t", () => __RΦ.a(13))(stringify);
|
|
31
|
+
export function getContent(xml) {
|
|
32
|
+
if (!("elements" in xml)) {
|
|
33
|
+
return "";
|
|
34
|
+
}
|
|
35
|
+
else if (xml.elements?.length === 1) {
|
|
36
|
+
const content = xml.elements[0];
|
|
37
|
+
if (content.type === "text")
|
|
38
|
+
return content.text;
|
|
39
|
+
}
|
|
40
|
+
throw new Error("this element doesn't contain text");
|
|
41
|
+
}
|
|
42
|
+
__RΦ.m("rt:p", [{ n: "xml", t: () => __RΦ.a(384), v: null }])(getContent);
|
|
43
|
+
__RΦ.m("rt:f", "F")(getContent);
|
|
44
|
+
__RΦ.m("rt:t", () => __RΦ.a(679))(getContent);
|
|
45
|
+
export function fromContent(content = "", tag, attributes) {
|
|
46
|
+
const el = {
|
|
47
|
+
type: "element",
|
|
48
|
+
elements: content ? [{ type: "text", text: String(content) }] : [],
|
|
49
|
+
};
|
|
50
|
+
if (tag)
|
|
51
|
+
el.name = tag;
|
|
52
|
+
if (attributes)
|
|
53
|
+
el.attributes = attributes;
|
|
54
|
+
return el;
|
|
55
|
+
}
|
|
56
|
+
__RΦ.m("rt:p", [{ n: "content", t: () => __RΦ.a(46), v: function () { return ""; } }, { n: "tag", t: () => __RΦ.a(13), v: null, f: "?" }, { n: "attributes", t: () => __RΦ.a(687), v: null, f: "?" }])(fromContent);
|
|
57
|
+
__RΦ.m("rt:f", "F")(fromContent);
|
|
58
|
+
__RΦ.m("rt:t", () => __RΦ.a(384))(fromContent);
|
|
59
|
+
export function addElement(xml, element) {
|
|
60
|
+
if (!xml.elements)
|
|
61
|
+
xml.elements = [];
|
|
62
|
+
xml.elements.push(element);
|
|
63
|
+
}
|
|
64
|
+
__RΦ.m("rt:p", [{ n: "xml", t: () => __RΦ.a(384), v: null }, { n: "element", t: () => __RΦ.a(384), v: null }])(addElement);
|
|
65
|
+
__RΦ.m("rt:f", "F")(addElement);
|
|
66
|
+
__RΦ.m("rt:t", () => __RΦ.a(22))(addElement);
|
|
67
|
+
const XML = {
|
|
68
|
+
parse,
|
|
69
|
+
stringify,
|
|
70
|
+
fromContent,
|
|
71
|
+
getContent,
|
|
72
|
+
addElement,
|
|
73
|
+
};
|
|
74
|
+
export default XML;
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "xml-model",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"main": "build/main/index.js",
|
|
5
|
+
"typings": "build/main/index.d.ts",
|
|
6
|
+
"module": "build/module/index.js",
|
|
7
|
+
"author": "MathisTLD",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"private": false,
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "yarn lint && mocha -r ./register-ts-node --colors src/**/*.spec.ts",
|
|
12
|
+
"build": "run-p build:*",
|
|
13
|
+
"build:main": "rimraf build/main && ttsc -p tsconfig.json",
|
|
14
|
+
"build:module": "rimraf build/module && ttsc -p tsconfig.module.json",
|
|
15
|
+
"lint": "eslint src/**/*.ts"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"lodash": "^4.17.21",
|
|
19
|
+
"reflect-metadata": "^0.1.13",
|
|
20
|
+
"typescript-rtti": "^0.7.3",
|
|
21
|
+
"xml-js": "^1.6.11"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/chai": "^4.3.1",
|
|
25
|
+
"@types/expect": "^24.3.0",
|
|
26
|
+
"@types/lodash": "^4.14.182",
|
|
27
|
+
"@types/mocha": "^9.1.1",
|
|
28
|
+
"@typescript-eslint/eslint-plugin": "^5.28.0",
|
|
29
|
+
"@typescript-eslint/parser": "^5.28.0",
|
|
30
|
+
"chai": "^4.3.6",
|
|
31
|
+
"eslint": "^8.18.0",
|
|
32
|
+
"mocha": "^10.0.0",
|
|
33
|
+
"npm-run-all": "^4.1.5",
|
|
34
|
+
"rimraf": "^3.0.2",
|
|
35
|
+
"ts-mocha": "^10.0.0",
|
|
36
|
+
"ts-node": "^10.8.1",
|
|
37
|
+
"ttypescript": "^1.5.13",
|
|
38
|
+
"typescript": "^4.7.4"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"build/main",
|
|
42
|
+
"build/module",
|
|
43
|
+
"!**/*.spec.*",
|
|
44
|
+
"CHANGELOG.md",
|
|
45
|
+
"LICENSE",
|
|
46
|
+
"README.md"
|
|
47
|
+
],
|
|
48
|
+
"description": "allows transparent XML <-> Object conversion in typescript",
|
|
49
|
+
"repository": "git@github.com:MathisTLD/xml-model.git"
|
|
50
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import type { XMLModelPropertyOptions } from "../model/types";
|
|
2
|
+
|
|
3
|
+
import type { XMLModelOptions, XMLModel } from "../model/types";
|
|
4
|
+
import { getModel } from "../model";
|
|
5
|
+
|
|
6
|
+
import kebabCase from "lodash/kebabCase";
|
|
7
|
+
import type { XMLElement, XMLRoot } from "../types";
|
|
8
|
+
|
|
9
|
+
type defaults<T = any> = {
|
|
10
|
+
// XML -> Object
|
|
11
|
+
fromXML: Required<XMLModelOptions<T>>["fromXML"]["middlewares"][number];
|
|
12
|
+
propertySourceElementsFilter: XMLModelPropertyOptions<T>["isSourceElement"];
|
|
13
|
+
propertyResolveSourceElements: XMLModelPropertyOptions<T>["resolveElements"];
|
|
14
|
+
propertyFromXML: Required<XMLModelPropertyOptions<T>>["fromXML"];
|
|
15
|
+
// Object -> XML
|
|
16
|
+
toXML: Required<XMLModelOptions<T>>["toXML"]["middlewares"][number];
|
|
17
|
+
tagnameFromModel: (model: XMLModel) => string;
|
|
18
|
+
tagnameFromProperty: (property: XMLModelPropertyOptions<T>) => string;
|
|
19
|
+
propertyToXML: Required<XMLModelPropertyOptions<T>>["toXML"];
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const defaults: defaults = {
|
|
23
|
+
fromXML() {
|
|
24
|
+
throw new TypeError(
|
|
25
|
+
"you should define 'defaults.fromXML' yourself or provide a 'fromXML' function to @Model() decorator's options"
|
|
26
|
+
);
|
|
27
|
+
},
|
|
28
|
+
propertyResolveSourceElements(context) {
|
|
29
|
+
// We assume context.xml.elements is a single tag containing all the props
|
|
30
|
+
// FIXME: is it safe ?
|
|
31
|
+
const innerElements: XMLElement[] = context.xml.elements[0]?.elements || [];
|
|
32
|
+
return innerElements.filter((el) =>
|
|
33
|
+
context.property.isSourceElement(el, context)
|
|
34
|
+
);
|
|
35
|
+
},
|
|
36
|
+
propertySourceElementsFilter(element, context) {
|
|
37
|
+
return context.property.tagname == element.name;
|
|
38
|
+
},
|
|
39
|
+
propertyFromXML(context) {
|
|
40
|
+
// TODO: handle inline
|
|
41
|
+
const prop = context.property;
|
|
42
|
+
const elements = context.elements;
|
|
43
|
+
const type = context.property.reflected.type;
|
|
44
|
+
if (prop.reflected.isOptional && elements.length === 0) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
if (type.is("class")) {
|
|
48
|
+
const model = getModel(type.class);
|
|
49
|
+
return model.fromXML({ elements: context.elements });
|
|
50
|
+
} else if (type.is("array")) {
|
|
51
|
+
let arrayEl: XMLElement = {};
|
|
52
|
+
if (
|
|
53
|
+
!prop.inline &&
|
|
54
|
+
elements.length === 1 &&
|
|
55
|
+
elements[0].name === prop.tagname
|
|
56
|
+
) {
|
|
57
|
+
// we assume our array is contained in a root tag
|
|
58
|
+
arrayEl = elements[0];
|
|
59
|
+
} else if (
|
|
60
|
+
prop.inline &&
|
|
61
|
+
elements.every((el) => el.name === prop.tagname)
|
|
62
|
+
) {
|
|
63
|
+
// we assume our array is contained in xml.elements
|
|
64
|
+
arrayEl = { elements };
|
|
65
|
+
}
|
|
66
|
+
if (arrayEl.elements) {
|
|
67
|
+
const elType = type.elementType;
|
|
68
|
+
if (elType.is("class")) {
|
|
69
|
+
const model = getModel(elType.class);
|
|
70
|
+
const xmlInstances = arrayEl.elements.map((el) => ({
|
|
71
|
+
elements: [el],
|
|
72
|
+
}));
|
|
73
|
+
return xmlInstances.map((xml) => model.fromXML(xml));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
} else if (
|
|
77
|
+
type.is("union") &&
|
|
78
|
+
type.types.length &&
|
|
79
|
+
type.types[0].is("literal")
|
|
80
|
+
) {
|
|
81
|
+
const firstType = type.types[0];
|
|
82
|
+
if (firstType.is("literal")) {
|
|
83
|
+
const firstTypeCtor = firstType.value.constructor;
|
|
84
|
+
if (
|
|
85
|
+
type.types.every(
|
|
86
|
+
(type) =>
|
|
87
|
+
type.is("literal") && type.value.constructor === firstTypeCtor
|
|
88
|
+
)
|
|
89
|
+
) {
|
|
90
|
+
// all elements of unions are litteral with same type
|
|
91
|
+
const model = getModel(firstTypeCtor);
|
|
92
|
+
return model.fromXML({ elements });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// TODO: should warn ???
|
|
98
|
+
return undefined;
|
|
99
|
+
},
|
|
100
|
+
/* Object -> XML */
|
|
101
|
+
toXML({ properties, model }) {
|
|
102
|
+
const elements: XMLElement[] = [];
|
|
103
|
+
|
|
104
|
+
model.options.properties.options.forEach((prop) => {
|
|
105
|
+
if (prop.name in properties && typeof prop.name !== "symbol") {
|
|
106
|
+
// FIXME: prop.name should never be a symbol anyway
|
|
107
|
+
const _xml = properties[prop.name] as XMLRoot;
|
|
108
|
+
// overwrite tagnames
|
|
109
|
+
_xml.elements.forEach((el) => {
|
|
110
|
+
(el.name = prop.tagname), // TODO: configurable ?
|
|
111
|
+
elements.push(el);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
return {
|
|
116
|
+
elements: [
|
|
117
|
+
{
|
|
118
|
+
type: "element",
|
|
119
|
+
name: model.options.tagname,
|
|
120
|
+
elements,
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
};
|
|
124
|
+
},
|
|
125
|
+
tagnameFromModel(model) {
|
|
126
|
+
return kebabCase(model.type.name);
|
|
127
|
+
},
|
|
128
|
+
tagnameFromProperty(property) {
|
|
129
|
+
return kebabCase(String(property.name));
|
|
130
|
+
},
|
|
131
|
+
propertyToXML(context) {
|
|
132
|
+
const property = context.property;
|
|
133
|
+
const type = property.reflected.type;
|
|
134
|
+
const value = context.value;
|
|
135
|
+
if (property.reflected.isOptional && typeof value === "undefined") {
|
|
136
|
+
return { elements: [] }; // FIXME should return unefined ???
|
|
137
|
+
}
|
|
138
|
+
const getXML = () => {
|
|
139
|
+
if (type.is("class")) {
|
|
140
|
+
const model = getModel(type.class);
|
|
141
|
+
return model.toXML(value);
|
|
142
|
+
} else if (type.is("array") && type.elementType.is("class")) {
|
|
143
|
+
const elementType = type.elementType;
|
|
144
|
+
if (elementType.is("class")) {
|
|
145
|
+
const model = getModel(elementType.class);
|
|
146
|
+
const elements: XMLElement[] = [];
|
|
147
|
+
(value as object[]).forEach((el) =>
|
|
148
|
+
elements.push(...model.toXML(el).elements)
|
|
149
|
+
);
|
|
150
|
+
return { elements: [{ type: "element", name: "array", elements }] };
|
|
151
|
+
}
|
|
152
|
+
// TODO: handle other types of array
|
|
153
|
+
} else if (
|
|
154
|
+
type.is("union") &&
|
|
155
|
+
type.types.length &&
|
|
156
|
+
type.types[0].is("literal")
|
|
157
|
+
) {
|
|
158
|
+
const firstType = type.types[0];
|
|
159
|
+
if (firstType.is("literal")) {
|
|
160
|
+
const firstTypeCtor = firstType.value.constructor;
|
|
161
|
+
if (
|
|
162
|
+
type.types.every(
|
|
163
|
+
(type) =>
|
|
164
|
+
type.is("literal") && type.value.constructor === firstTypeCtor
|
|
165
|
+
)
|
|
166
|
+
) {
|
|
167
|
+
// all elements of unions are litteral with same type
|
|
168
|
+
const model = getModel(firstTypeCtor);
|
|
169
|
+
return model.toXML(context.value);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// TODO: should warn ???
|
|
174
|
+
return { elements: [] };
|
|
175
|
+
};
|
|
176
|
+
const xml = getXML();
|
|
177
|
+
if (context.property.inline)
|
|
178
|
+
return { elements: xml.elements.map((el) => el.elements || []).flat() };
|
|
179
|
+
else return xml;
|
|
180
|
+
},
|
|
181
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { createModel } from "../model";
|
|
2
|
+
import { Constructor } from "../types";
|
|
3
|
+
import { getContent, fromContent } from "../xml";
|
|
4
|
+
|
|
5
|
+
// string is <string>value</string>
|
|
6
|
+
createModel<string>(String as unknown as Constructor<string>, {
|
|
7
|
+
toXML: (ctx) => {
|
|
8
|
+
return {
|
|
9
|
+
elements: [fromContent(ctx.object, "string")],
|
|
10
|
+
};
|
|
11
|
+
},
|
|
12
|
+
fromXML: (ctx) => {
|
|
13
|
+
return String(getContent(ctx.xml.elements[0]));
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
// number is <number>value</number>
|
|
18
|
+
createModel<number>(Number as unknown as Constructor<number>, {
|
|
19
|
+
toXML: (ctx) => {
|
|
20
|
+
return {
|
|
21
|
+
elements: [fromContent(String(ctx.object), "number")],
|
|
22
|
+
};
|
|
23
|
+
},
|
|
24
|
+
fromXML: (ctx) => {
|
|
25
|
+
return Number(getContent(ctx.xml.elements[0]));
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// number is <boolean>value</boolean>
|
|
30
|
+
createModel<boolean>(Boolean as unknown as Constructor<boolean>, {
|
|
31
|
+
toXML: (ctx) => {
|
|
32
|
+
return {
|
|
33
|
+
elements: [
|
|
34
|
+
{
|
|
35
|
+
type: "element",
|
|
36
|
+
name: "boolean",
|
|
37
|
+
...fromContent(String(ctx.object)),
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
};
|
|
41
|
+
},
|
|
42
|
+
fromXML: (ctx) => {
|
|
43
|
+
return Boolean(getContent(ctx.xml.elements[0]));
|
|
44
|
+
},
|
|
45
|
+
});
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export type Middleware<C, T> = (context: C, next: () => T) => T;
|
|
2
|
+
|
|
3
|
+
interface ChainableOptions<C, T> {
|
|
4
|
+
parent: ChainableOptions<C, T> | null;
|
|
5
|
+
middlewares: Middleware<C, T>[];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function* MiddlewareChain<C, T>(options: ChainableOptions<C, T>) {
|
|
9
|
+
do {
|
|
10
|
+
for (let index = options.middlewares.length - 1; index >= 0; index--) {
|
|
11
|
+
yield options.middlewares[index];
|
|
12
|
+
}
|
|
13
|
+
if (options.parent) options = options.parent;
|
|
14
|
+
else return;
|
|
15
|
+
} while (true);
|
|
16
|
+
}
|
|
17
|
+
type MiddlewareChain<C, T> = Iterator<Middleware<C, T>>;
|
|
18
|
+
|
|
19
|
+
export function resolve<C, T>(
|
|
20
|
+
middlewares: MiddlewareChain<C, T>,
|
|
21
|
+
context: C
|
|
22
|
+
): T {
|
|
23
|
+
const next = (): T => {
|
|
24
|
+
const { value: nextMiddleware, done } = middlewares.next();
|
|
25
|
+
if (done || !nextMiddleware) {
|
|
26
|
+
// previous middlewares should have returned a value before
|
|
27
|
+
// TODO: dedicated error class
|
|
28
|
+
throw new Error("no more next middleware");
|
|
29
|
+
} else {
|
|
30
|
+
return nextMiddleware(context, next);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
return next();
|
|
34
|
+
}
|