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.
Files changed (65) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc.js +6 -0
  3. package/.gitignore +2 -0
  4. package/.vscode/launch.json +21 -0
  5. package/.vscode/settings.json +3 -0
  6. package/README.md +7 -0
  7. package/build/main/defaults/index.d.ts +14 -0
  8. package/build/main/defaults/index.js +165 -0
  9. package/build/main/defaults/models.d.ts +1 -0
  10. package/build/main/defaults/models.js +55 -0
  11. package/build/main/index.d.ts +5 -0
  12. package/build/main/index.js +31 -0
  13. package/build/main/middleware.d.ts +9 -0
  14. package/build/main/middleware.js +65 -0
  15. package/build/main/model/index.d.ts +26 -0
  16. package/build/main/model/index.js +304 -0
  17. package/build/main/model/property.d.ts +5 -0
  18. package/build/main/model/property.js +95 -0
  19. package/build/main/model/types.d.ts +69 -0
  20. package/build/main/model/types.js +214 -0
  21. package/build/main/model.spec.d.ts +1 -0
  22. package/build/main/model.spec.js +261 -0
  23. package/build/main/types.d.ts +8 -0
  24. package/build/main/types.js +18 -0
  25. package/build/main/xml.d.ts +31 -0
  26. package/build/main/xml.js +95 -0
  27. package/build/module/defaults/index.d.ts +13 -0
  28. package/build/module/defaults/index.js +71 -0
  29. package/build/module/defaults/models.d.ts +1 -0
  30. package/build/module/defaults/models.js +27 -0
  31. package/build/module/errors.d.ts +3 -0
  32. package/build/module/errors.js +37 -0
  33. package/build/module/index.d.ts +4 -0
  34. package/build/module/index.js +19 -0
  35. package/build/module/middleware.d.ts +9 -0
  36. package/build/module/middleware.js +60 -0
  37. package/build/module/model.d.ts +71 -0
  38. package/build/module/model.js +466 -0
  39. package/build/module/model.spec.d.ts +1 -0
  40. package/build/module/model.spec.js +76 -0
  41. package/build/module/types.d.ts +13 -0
  42. package/build/module/types.js +40 -0
  43. package/build/module/xml-from-object.d.ts +11 -0
  44. package/build/module/xml-from-object.js +58 -0
  45. package/build/module/xml-from-object.spec.d.ts +1 -0
  46. package/build/module/xml-from-object.spec.js +104 -0
  47. package/build/module/xml-to-object.d.ts +11 -0
  48. package/build/module/xml-to-object.js +55 -0
  49. package/build/module/xml.d.ts +15 -0
  50. package/build/module/xml.js +74 -0
  51. package/package.json +50 -0
  52. package/register-ts-node.js +9 -0
  53. package/src/defaults/index.ts +181 -0
  54. package/src/defaults/models.ts +45 -0
  55. package/src/index.ts +6 -0
  56. package/src/middleware.ts +34 -0
  57. package/src/model/index.ts +245 -0
  58. package/src/model/property.ts +104 -0
  59. package/src/model/types.ts +99 -0
  60. package/src/model.spec.ts +178 -0
  61. package/src/types.ts +8 -0
  62. package/src/xml.ts +80 -0
  63. package/tsconfig.json +106 -0
  64. package/tsconfig.module.json +9 -0
  65. 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,9 @@
1
+ try {
2
+ require("ts-node").register({
3
+ project: "./tsconfig.json",
4
+ compiler: "ttypescript",
5
+ });
6
+ } catch (error) {
7
+ console.log("[ERROR] " + error.message);
8
+ process.exit(1);
9
+ }
@@ -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,6 @@
1
+ export type { XMLElement, XMLRoot, Constructor } from "./types";
2
+ export { defaults } from "./defaults";
3
+ export { getModel, createModel, Model, Prop } from "./model";
4
+
5
+ import XML from "./xml";
6
+ export { XML };
@@ -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
+ }