@singularsystems/neo-core 1.0.13 → 1.0.15
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/dist/Data/Deserialiser.js +10 -6
- package/dist/Model/Decorators.d.ts +3 -1
- package/dist/Model/Decorators.js +3 -1
- package/dist/Model/IModelBase.d.ts +5 -0
- package/dist/Model/List.d.ts +10 -4
- package/dist/Model/List.js +27 -4
- package/dist/Model/ModelBase.d.ts +1 -1
- package/dist/Model/ModelCreatorBase.js +3 -2
- package/dist/Model/NeoTypeInfo.d.ts +1 -0
- package/dist/Model/NeoTypeInfo.js +7 -0
- package/dist/Model/PropertyInfo.d.ts +5 -3
- package/dist/Model/PropertyInfo.js +12 -4
- package/package.json +2 -2
|
@@ -63,7 +63,7 @@ var Deserialiser = /** @class */ (function () {
|
|
|
63
63
|
}
|
|
64
64
|
});
|
|
65
65
|
};
|
|
66
|
-
Deserialiser.prototype.deserialiseArray = function (from, to, type) {
|
|
66
|
+
Deserialiser.prototype.deserialiseArray = function (from, to, type, itemFactory) {
|
|
67
67
|
if (!to) {
|
|
68
68
|
throw "Cannot deserialise array into a non initialised property.";
|
|
69
69
|
}
|
|
@@ -99,7 +99,10 @@ var Deserialiser = /** @class */ (function () {
|
|
|
99
99
|
deserialise = false;
|
|
100
100
|
}
|
|
101
101
|
else {
|
|
102
|
-
if (
|
|
102
|
+
if (itemFactory) {
|
|
103
|
+
toItem = itemFactory(fromItem);
|
|
104
|
+
}
|
|
105
|
+
else if (type) {
|
|
103
106
|
toItem = new type();
|
|
104
107
|
}
|
|
105
108
|
else {
|
|
@@ -130,13 +133,14 @@ var Deserialiser = /** @class */ (function () {
|
|
|
130
133
|
else {
|
|
131
134
|
var mustCreate = !to[key];
|
|
132
135
|
if (mustCreate) {
|
|
133
|
-
to[key] = parentProperty.createValueInstance();
|
|
136
|
+
to[key] = parentProperty.createValueInstance(fromItem);
|
|
134
137
|
}
|
|
135
138
|
this.deserialiseObject(fromItem, to[key], mustCreate);
|
|
136
139
|
}
|
|
137
140
|
}
|
|
138
141
|
};
|
|
139
142
|
Deserialiser.prototype.deserialiseObject = function (from, to, justCreated) {
|
|
143
|
+
var _a;
|
|
140
144
|
if (!from || !to) {
|
|
141
145
|
throw "From and to objects are required.";
|
|
142
146
|
}
|
|
@@ -173,9 +177,9 @@ var Deserialiser = /** @class */ (function () {
|
|
|
173
177
|
}
|
|
174
178
|
else {
|
|
175
179
|
if (fromValue instanceof Array && !propertyInfo.assignOnDeserialise) {
|
|
176
|
-
if (!to[key] || !(to[key] instanceof Array) || to[key].
|
|
180
|
+
if (!to[key] || !(to[key] instanceof Array) || to[key].canDeserialise) {
|
|
177
181
|
// Deserialise into full list.
|
|
178
|
-
this.deserialiseArray(fromValue, to[key], undefined);
|
|
182
|
+
this.deserialiseArray(fromValue, to[key], undefined, (_a = to[key]) === null || _a === void 0 ? void 0 : _a.itemFactory);
|
|
179
183
|
}
|
|
180
184
|
else {
|
|
181
185
|
// Plain array
|
|
@@ -197,7 +201,7 @@ var Deserialiser = /** @class */ (function () {
|
|
|
197
201
|
else {
|
|
198
202
|
var mustCreate = !to[key];
|
|
199
203
|
if (mustCreate) {
|
|
200
|
-
to[key] = propertyInfo.createValueInstance();
|
|
204
|
+
to[key] = propertyInfo.createValueInstance(fromValue);
|
|
201
205
|
}
|
|
202
206
|
this.deserialiseObject(fromValue, to[key], mustCreate);
|
|
203
207
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SerialiseType, DataType, TimeZoneFormat } from './Misc';
|
|
2
|
+
import { IObjectFactoryOptions } from './IModelBase';
|
|
2
3
|
export declare function Display(name: string): (type: any, propertyKey: string) => void;
|
|
3
4
|
/** Indicates that this is a date property. Json strings will be converted to date objects on deserialisation. */
|
|
4
5
|
export declare function Date(timeZoneSerialisation?: TimeZoneFormat): (type: any, propertyKey: string, descriptor?: PropertyDescriptor) => void;
|
|
@@ -20,10 +21,11 @@ export declare function Observable(isObservable?: boolean): (type: any, property
|
|
|
20
21
|
export declare function NoTracking(serialisation?: SerialiseType): (type: any, propertyKey: string) => void;
|
|
21
22
|
export declare function Serialisation(serialisation: SerialiseType): (type: any, propertyKey: string) => void;
|
|
22
23
|
/** Indicates that this is a list property, and specifies the item type. This is not required if the list is initialised with a value. */
|
|
23
|
-
export declare function ChildList(childType
|
|
24
|
+
export declare function ChildList(childType?: (new () => any) | (() => any) | IObjectFactoryOptions): (type: any, propertyKey: string) => any;
|
|
24
25
|
/** Indicates that this is a child object property, and specifies the child type. This is not required if the property is initialised with a value. */
|
|
25
26
|
export declare function ChildObject(childType: new () => any, isValueObject?: boolean): Function;
|
|
26
27
|
export declare function ChildObject(childType: () => any, isValueObject?: boolean): Function;
|
|
28
|
+
export declare function ChildObject(options: IObjectFactoryOptions, isValueObject?: boolean): Function;
|
|
27
29
|
export declare function Dictionary(valueType: any): (type: any, propertyKey: string) => any;
|
|
28
30
|
export declare function Parent(parentType: () => any): (type: any, propertyKey: string) => void;
|
|
29
31
|
/**
|
package/dist/Model/Decorators.js
CHANGED
|
@@ -85,7 +85,9 @@ export function Serialisation(serialisation) {
|
|
|
85
85
|
export function ChildList(childType) {
|
|
86
86
|
return function (type, propertyKey) {
|
|
87
87
|
var pi = getOrAddPropertyInfo(type, propertyKey);
|
|
88
|
-
|
|
88
|
+
if (childType) {
|
|
89
|
+
pi.setPropertyType(childType);
|
|
90
|
+
}
|
|
89
91
|
if (pi.relationType === RelationType.None) {
|
|
90
92
|
pi.relationType = RelationType.ChildList;
|
|
91
93
|
pi.propertyType = DataType.Array;
|
|
@@ -101,4 +101,9 @@ export interface IModelBase extends INonObservableModelBase {
|
|
|
101
101
|
readonly isDirty: boolean;
|
|
102
102
|
readonly readyToSave: boolean;
|
|
103
103
|
}
|
|
104
|
+
export type ObjectFactory = (rawData: object) => object;
|
|
105
|
+
export interface IObjectFactoryOptions {
|
|
106
|
+
/** Function that creates an instance of an object based on some input data. */
|
|
107
|
+
itemFactory: ObjectFactory;
|
|
108
|
+
}
|
|
104
109
|
export {};
|
package/dist/Model/List.d.ts
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { ISerialiseOptions } from '../Data/Serialiser';
|
|
2
|
-
import { PlainObject, PartialPlainObject, PlainTrackedObject, IMetaItem } from './IModelBase';
|
|
2
|
+
import { PlainObject, PartialPlainObject, PlainTrackedObject, IMetaItem, ObjectFactory, IObjectFactoryOptions } from './IModelBase';
|
|
3
3
|
import { IDeserialiseOptions } from '../Data/Deserialiser';
|
|
4
4
|
export default class List<T> extends Array<T> {
|
|
5
|
-
childObjectType: (new () => T);
|
|
6
5
|
attachedTo: object | null;
|
|
6
|
+
childObjectType?: new () => T;
|
|
7
|
+
itemFactory?: ObjectFactory;
|
|
7
8
|
private _deletedList;
|
|
8
9
|
get deletedList(): T[];
|
|
10
|
+
get canDeserialise(): ObjectFactory | (new () => T) | undefined;
|
|
9
11
|
private baseMethods;
|
|
10
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Creates an instance of a list. A List is an array with the ability to auto create child instances, and track removed items.
|
|
14
|
+
* @param childObjectType Usually the type that the list contains. Can also pass in options for advanced usage.
|
|
15
|
+
*/
|
|
16
|
+
constructor(childObjectType?: (new () => T) | IObjectFactoryOptions);
|
|
11
17
|
/**
|
|
12
18
|
* Copies the methods and properties from the prototype to the new instance.
|
|
13
19
|
* This is needed because vue / mobx changes the prototype to its own.
|
|
@@ -69,7 +75,7 @@ export default class List<T> extends Array<T> {
|
|
|
69
75
|
removeWithoutTracking(item: T): void;
|
|
70
76
|
private removeItem;
|
|
71
77
|
/** Returns a static meta object containing all the properties of the lists item type. */
|
|
72
|
-
getMetaItem(): IMetaItem;
|
|
78
|
+
getMetaItem(): IMetaItem | null;
|
|
73
79
|
/** True if all items in the list are valid. */
|
|
74
80
|
get isValid(): boolean;
|
|
75
81
|
/** True if any item in the list is dirty, or the list contains any deleted items. */
|
package/dist/Model/List.js
CHANGED
|
@@ -5,10 +5,19 @@ import { ObservableValue } from './ObservableValue';
|
|
|
5
5
|
import { NeoTypeInfo } from './NeoTypeInfo';
|
|
6
6
|
var List = /** @class */ (function (_super) {
|
|
7
7
|
__extends(List, _super);
|
|
8
|
+
/**
|
|
9
|
+
* Creates an instance of a list. A List is an array with the ability to auto create child instances, and track removed items.
|
|
10
|
+
* @param childObjectType Usually the type that the list contains. Can also pass in options for advanced usage.
|
|
11
|
+
*/
|
|
8
12
|
function List(childObjectType) {
|
|
9
13
|
var _this = _super.call(this) || this;
|
|
10
|
-
_this.childObjectType = childObjectType;
|
|
11
14
|
_this._deletedList = new ObservableValue([]);
|
|
15
|
+
if (typeof childObjectType === "function") {
|
|
16
|
+
_this.childObjectType = childObjectType;
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
_this.itemFactory = childObjectType === null || childObjectType === void 0 ? void 0 : childObjectType.itemFactory;
|
|
20
|
+
}
|
|
12
21
|
List.copyMethods(_this);
|
|
13
22
|
return _this;
|
|
14
23
|
}
|
|
@@ -19,6 +28,13 @@ var List = /** @class */ (function (_super) {
|
|
|
19
28
|
enumerable: false,
|
|
20
29
|
configurable: true
|
|
21
30
|
});
|
|
31
|
+
Object.defineProperty(List.prototype, "canDeserialise", {
|
|
32
|
+
get: function () {
|
|
33
|
+
return this.itemFactory || this.childObjectType;
|
|
34
|
+
},
|
|
35
|
+
enumerable: false,
|
|
36
|
+
configurable: true
|
|
37
|
+
});
|
|
22
38
|
/**
|
|
23
39
|
* Copies the methods and properties from the prototype to the new instance.
|
|
24
40
|
* This is needed because vue / mobx changes the prototype to its own.
|
|
@@ -45,6 +61,7 @@ var List = /** @class */ (function (_super) {
|
|
|
45
61
|
};
|
|
46
62
|
List.prototype.setupProxy = function (proxy, attachedTo) {
|
|
47
63
|
proxy.childObjectType = this.childObjectType;
|
|
64
|
+
proxy.itemFactory = this.itemFactory;
|
|
48
65
|
proxy._deletedList = new ObservableValue([]);
|
|
49
66
|
proxy.attachedTo = attachedTo;
|
|
50
67
|
};
|
|
@@ -80,6 +97,9 @@ var List = /** @class */ (function (_super) {
|
|
|
80
97
|
};
|
|
81
98
|
/** Creates a new item of type T */
|
|
82
99
|
List.prototype.createChild = function () {
|
|
100
|
+
if (!this.childObjectType) {
|
|
101
|
+
throw "Cannot create child, type was not passed to constructor.";
|
|
102
|
+
}
|
|
83
103
|
return new this.childObjectType();
|
|
84
104
|
};
|
|
85
105
|
List.prototype.push = function () {
|
|
@@ -89,7 +109,7 @@ var List = /** @class */ (function (_super) {
|
|
|
89
109
|
items[_i] = arguments[_i];
|
|
90
110
|
}
|
|
91
111
|
items.forEach(function (item) {
|
|
92
|
-
if (!(item instanceof _this.childObjectType)) {
|
|
112
|
+
if (_this.childObjectType && !(item instanceof _this.childObjectType)) {
|
|
93
113
|
throw "Type error, cannot add item of type " + Utils.getTypeName(item.constructor) + " to list of type " + Utils.getTypeName(_this.childObjectType) + ".";
|
|
94
114
|
}
|
|
95
115
|
_this.setParent(item);
|
|
@@ -101,7 +121,7 @@ var List = /** @class */ (function (_super) {
|
|
|
101
121
|
};
|
|
102
122
|
List.prototype.setParent = function (item) {
|
|
103
123
|
if (this.attachedTo) {
|
|
104
|
-
var itemConstructor =
|
|
124
|
+
var itemConstructor = item.constructor.prototype.constructor;
|
|
105
125
|
// set the parent property
|
|
106
126
|
if (itemConstructor.neo) {
|
|
107
127
|
var parentConstructor = this.attachedTo.constructor.prototype.constructor;
|
|
@@ -162,10 +182,13 @@ var List = /** @class */ (function (_super) {
|
|
|
162
182
|
if (this.length) {
|
|
163
183
|
return this[0];
|
|
164
184
|
}
|
|
165
|
-
else {
|
|
185
|
+
else if (this.childObjectType) {
|
|
166
186
|
var ctor = this.childObjectType.prototype.constructor;
|
|
167
187
|
return NeoTypeInfo.ensureInitialised(ctor).metaItem;
|
|
168
188
|
}
|
|
189
|
+
else {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
169
192
|
};
|
|
170
193
|
Object.defineProperty(List.prototype, "isValid", {
|
|
171
194
|
/** True if all items in the list are valid. */
|
|
@@ -83,7 +83,7 @@ export default abstract class ModelBase extends BindableBase implements IModelBa
|
|
|
83
83
|
* ```
|
|
84
84
|
* protected static addBusinessRules(rules: ValidationRules<MyType>) {
|
|
85
85
|
* ``` */
|
|
86
|
-
protected addBusinessRules(validationRules: ValidationRules<
|
|
86
|
+
protected addBusinessRules(validationRules: ValidationRules<ModelBase>): void;
|
|
87
87
|
/**
|
|
88
88
|
* Add custom business rules for this type.
|
|
89
89
|
*/
|
|
@@ -61,11 +61,12 @@ var ModelCreatorBase = /** @class */ (function () {
|
|
|
61
61
|
// @ts-ignore
|
|
62
62
|
var propertyValue = instance[propertyInfo.propertyName];
|
|
63
63
|
if (propertyValue) {
|
|
64
|
-
|
|
64
|
+
var list = propertyValue;
|
|
65
|
+
if (list.itemFactory || list.childObjectType) {
|
|
65
66
|
// This is a list.
|
|
66
67
|
if (propertyInfo.relationType != RelationType.ChildList) {
|
|
67
68
|
// add missing annotation
|
|
68
|
-
propertyInfo = ChildList(
|
|
69
|
+
propertyInfo = ChildList(list.itemFactory ? { itemFactory: list.itemFactory } : list.childObjectType)(instance, propertyInfo.propertyName);
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
else if (propertyValue instanceof ModelBase) {
|
|
@@ -22,6 +22,7 @@ export declare class NeoTypeInfo {
|
|
|
22
22
|
get inheritsBindableBase(): boolean;
|
|
23
23
|
get inheritsModelBase(): boolean;
|
|
24
24
|
get metaItem(): IMetaItem;
|
|
25
|
+
get typeName(): string;
|
|
25
26
|
initialise(objectConstructor: NeoModelConstructor): void;
|
|
26
27
|
private addPropertyInfo;
|
|
27
28
|
getOrAddProperty(propertyName: string): PropertyInfo;
|
|
@@ -55,6 +55,13 @@ var NeoTypeInfo = /** @class */ (function () {
|
|
|
55
55
|
enumerable: false,
|
|
56
56
|
configurable: true
|
|
57
57
|
});
|
|
58
|
+
Object.defineProperty(NeoTypeInfo.prototype, "typeName", {
|
|
59
|
+
get: function () {
|
|
60
|
+
return this.objectConstructor.name;
|
|
61
|
+
},
|
|
62
|
+
enumerable: false,
|
|
63
|
+
configurable: true
|
|
64
|
+
});
|
|
58
65
|
NeoTypeInfo.prototype.initialise = function (objectConstructor) {
|
|
59
66
|
this.objectConstructor = objectConstructor;
|
|
60
67
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SerialiseType, RelationType, OnChangedOptions, DataType, TimeZoneFormat } from './Misc';
|
|
2
2
|
import { Nullable } from '../Utils';
|
|
3
|
-
import { INonObservableModelBase } from './IModelBase';
|
|
3
|
+
import { INonObservableModelBase, IObjectFactoryOptions, ObjectFactory } from './IModelBase';
|
|
4
4
|
import { Rule } from '../Validation/Rules';
|
|
5
5
|
export type PropertyInfoMap = {
|
|
6
6
|
[index: string]: PropertyInfo;
|
|
@@ -58,6 +58,8 @@ export default class PropertyInfo {
|
|
|
58
58
|
rules: Rule[];
|
|
59
59
|
/** Indicates that this property must be assigned to on de/serialisation. The de/serialiser will not try create a model instance of the object / array. */
|
|
60
60
|
assignOnDeserialise: boolean;
|
|
61
|
+
/** Object factory used for deserialisation. Set by ChildList / ChildObject decorators. */
|
|
62
|
+
itemFactory?: ObjectFactory;
|
|
61
63
|
constructor(propertyName: string);
|
|
62
64
|
/** Gets the readable name of the property. Uses string.readable if Display decorator was not specified. */
|
|
63
65
|
get readableName(): string;
|
|
@@ -67,7 +69,7 @@ export default class PropertyInfo {
|
|
|
67
69
|
get parent(): PropertyInfo | undefined;
|
|
68
70
|
addAttributeRule(rule: Rule): void;
|
|
69
71
|
clone(): PropertyInfo;
|
|
70
|
-
setPropertyType(propertyType: (() => any) | (new () => any)): void;
|
|
72
|
+
setPropertyType(propertyType: (() => any) | (new () => any) | IObjectFactoryOptions): void;
|
|
71
73
|
/**
|
|
72
74
|
* Gets the constructor function of the return type.
|
|
73
75
|
* Returns null if the property has not been decorated with a ChildObject / Parent attribute.
|
|
@@ -78,6 +80,6 @@ export default class PropertyInfo {
|
|
|
78
80
|
* Raises an error if the property has not been decorated with a ChildObject / Parent attribute.
|
|
79
81
|
*/
|
|
80
82
|
get typeWithAssert(): new () => any;
|
|
81
|
-
createValueInstance(): any;
|
|
83
|
+
createValueInstance(data: any): any;
|
|
82
84
|
setupFromInstance(instance: any): void;
|
|
83
85
|
}
|
|
@@ -75,11 +75,16 @@ var PropertyInfo = /** @class */ (function () {
|
|
|
75
75
|
return clone;
|
|
76
76
|
};
|
|
77
77
|
PropertyInfo.prototype.setPropertyType = function (propertyType) {
|
|
78
|
-
if (
|
|
79
|
-
|
|
78
|
+
if (typeof propertyType === "function") {
|
|
79
|
+
if (!propertyType.prototype || !propertyType.prototype.constructor.name) {
|
|
80
|
+
this.typeCallback = propertyType;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
this._type = propertyType;
|
|
84
|
+
}
|
|
80
85
|
}
|
|
81
86
|
else {
|
|
82
|
-
this.
|
|
87
|
+
this.itemFactory = propertyType.itemFactory;
|
|
83
88
|
}
|
|
84
89
|
};
|
|
85
90
|
Object.defineProperty(PropertyInfo.prototype, "type", {
|
|
@@ -116,7 +121,10 @@ var PropertyInfo = /** @class */ (function () {
|
|
|
116
121
|
enumerable: false,
|
|
117
122
|
configurable: true
|
|
118
123
|
});
|
|
119
|
-
PropertyInfo.prototype.createValueInstance = function () {
|
|
124
|
+
PropertyInfo.prototype.createValueInstance = function (data) {
|
|
125
|
+
if (this.itemFactory) {
|
|
126
|
+
return this.itemFactory(data);
|
|
127
|
+
}
|
|
120
128
|
try {
|
|
121
129
|
return new this.typeWithAssert();
|
|
122
130
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@singularsystems/neo-core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.15",
|
|
4
4
|
"description": "Core functionality for the Neo client library",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@microsoft/signalr": "^6.0.1",
|
|
28
|
-
"axios": "1.
|
|
28
|
+
"axios": "1.7.4",
|
|
29
29
|
"inversify": "^6.0.2",
|
|
30
30
|
"reflect-metadata": "0.1.13",
|
|
31
31
|
"tslib": "2.5.0"
|