@quatrain/core 1.1.24 → 1.1.28

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 (234) hide show
  1. package/README.md +56 -8
  2. package/{lib → dist}/Core.d.ts +3 -17
  3. package/dist/Core.d.ts.map +1 -0
  4. package/dist/Core.js +105 -0
  5. package/dist/Core.js.map +1 -0
  6. package/dist/common/DataGenerator.d.ts +3 -0
  7. package/dist/common/DataGenerator.d.ts.map +1 -0
  8. package/dist/common/DataGenerator.js +86 -0
  9. package/dist/common/DataGenerator.js.map +1 -0
  10. package/{lib → dist}/common/ResourcesErrors.d.ts +1 -0
  11. package/dist/common/ResourcesErrors.d.ts.map +1 -0
  12. package/{lib → dist}/common/ResourcesErrors.js +1 -0
  13. package/dist/common/ResourcesErrors.js.map +1 -0
  14. package/{lib → dist}/common/statuses.d.ts +1 -0
  15. package/dist/common/statuses.d.ts.map +1 -0
  16. package/{lib → dist}/common/statuses.js +1 -0
  17. package/dist/common/statuses.js.map +1 -0
  18. package/{lib → dist}/components/AbstractObject.d.ts +1 -5
  19. package/dist/components/AbstractObject.d.ts.map +1 -0
  20. package/{lib → dist}/components/AbstractObject.js +7 -10
  21. package/dist/components/AbstractObject.js.map +1 -0
  22. package/{lib → dist}/components/BaseObject.d.ts +4 -17
  23. package/dist/components/BaseObject.d.ts.map +1 -0
  24. package/dist/components/BaseObject.js +71 -0
  25. package/dist/components/BaseObject.js.map +1 -0
  26. package/dist/components/BaseObjectProperties.d.ts +2 -0
  27. package/dist/components/BaseObjectProperties.d.ts.map +1 -0
  28. package/{lib → dist}/components/BaseObjectProperties.js +1 -2
  29. package/dist/components/BaseObjectProperties.js.map +1 -0
  30. package/{lib → dist}/components/DataObject.d.ts +2 -51
  31. package/dist/components/DataObject.d.ts.map +1 -0
  32. package/{lib → dist}/components/DataObject.js +38 -111
  33. package/dist/components/DataObject.js.map +1 -0
  34. package/{lib → dist}/components/Entity.d.ts +1 -0
  35. package/dist/components/Entity.d.ts.map +1 -0
  36. package/dist/components/Entity.js +48 -0
  37. package/dist/components/Entity.js.map +1 -0
  38. package/{lib → dist}/components/ObjectUri.d.ts +1 -26
  39. package/dist/components/ObjectUri.d.ts.map +1 -0
  40. package/{lib → dist}/components/ObjectUri.js +13 -41
  41. package/dist/components/ObjectUri.js.map +1 -0
  42. package/{lib → dist}/components/User.d.ts +1 -0
  43. package/dist/components/User.d.ts.map +1 -0
  44. package/{lib → dist}/components/User.js +7 -26
  45. package/dist/components/User.js.map +1 -0
  46. package/dist/components/__test__/fixtures/dao.d.ts +37 -0
  47. package/dist/components/__test__/fixtures/dao.d.ts.map +1 -0
  48. package/dist/components/__test__/fixtures/dao.js +100 -0
  49. package/dist/components/__test__/fixtures/dao.js.map +1 -0
  50. package/{lib → dist}/components/index.d.ts +5 -2
  51. package/dist/components/index.d.ts.map +1 -0
  52. package/{lib → dist}/components/index.js +1 -0
  53. package/dist/components/index.js.map +1 -0
  54. package/{lib → dist}/components/types/AbstractObjectClass.d.ts +1 -0
  55. package/dist/components/types/AbstractObjectClass.d.ts.map +1 -0
  56. package/dist/components/types/AbstractObjectClass.js +3 -0
  57. package/dist/components/types/AbstractObjectClass.js.map +1 -0
  58. package/{lib → dist}/components/types/BaseObjectClass.d.ts +1 -0
  59. package/dist/components/types/BaseObjectClass.d.ts.map +1 -0
  60. package/{lib → dist}/components/types/BaseObjectClass.js +1 -0
  61. package/dist/components/types/BaseObjectClass.js.map +1 -0
  62. package/{lib → dist}/components/types/BaseObjectType.d.ts +2 -1
  63. package/dist/components/types/BaseObjectType.d.ts.map +1 -0
  64. package/{lib → dist}/components/types/BaseObjectType.js +1 -0
  65. package/dist/components/types/BaseObjectType.js.map +1 -0
  66. package/{lib → dist}/components/types/DataObjectClass.d.ts +1 -0
  67. package/dist/components/types/DataObjectClass.d.ts.map +1 -0
  68. package/{lib → dist}/components/types/DataObjectClass.js +1 -0
  69. package/dist/components/types/DataObjectClass.js.map +1 -0
  70. package/dist/components/types/DataObjectParams.d.ts +8 -0
  71. package/dist/components/types/DataObjectParams.d.ts.map +1 -0
  72. package/dist/components/types/DataObjectParams.js +3 -0
  73. package/dist/components/types/DataObjectParams.js.map +1 -0
  74. package/{lib → dist}/components/types/DataObjectType.d.ts +1 -0
  75. package/dist/components/types/DataObjectType.d.ts.map +1 -0
  76. package/{lib → dist}/components/types/DataObjectType.js +1 -0
  77. package/dist/components/types/DataObjectType.js.map +1 -0
  78. package/{lib → dist}/components/types/EntityClass.d.ts +1 -0
  79. package/dist/components/types/EntityClass.d.ts.map +1 -0
  80. package/{lib → dist}/components/types/EntityClass.js +1 -0
  81. package/dist/components/types/EntityClass.js.map +1 -0
  82. package/{lib → dist}/components/types/Payload.d.ts +1 -0
  83. package/dist/components/types/Payload.d.ts.map +1 -0
  84. package/{lib → dist}/components/types/Payload.js +1 -0
  85. package/dist/components/types/Payload.js.map +1 -0
  86. package/{lib → dist}/components/types/Persisted.d.ts +1 -0
  87. package/dist/components/types/Persisted.d.ts.map +1 -0
  88. package/{lib → dist}/components/types/Persisted.js +1 -0
  89. package/dist/components/types/Persisted.js.map +1 -0
  90. package/dist/components/types/Properties.d.ts +2 -0
  91. package/dist/components/types/Properties.d.ts.map +1 -0
  92. package/{lib/components/types/AbstractObjectClass.js → dist/components/types/Properties.js} +1 -0
  93. package/dist/components/types/Properties.js.map +1 -0
  94. package/{lib → dist}/components/types/ProxyConstructor.d.ts +1 -0
  95. package/dist/components/types/ProxyConstructor.d.ts.map +1 -0
  96. package/{lib → dist}/components/types/ProxyConstructor.js +1 -0
  97. package/dist/components/types/ProxyConstructor.js.map +1 -0
  98. package/{lib → dist}/components/types/toJSONParams.d.ts +1 -0
  99. package/dist/components/types/toJSONParams.d.ts.map +1 -0
  100. package/{lib → dist}/components/types/toJSONParams.js +1 -0
  101. package/dist/components/types/toJSONParams.js.map +1 -0
  102. package/{lib → dist}/index.d.ts +5 -1
  103. package/dist/index.d.ts.map +1 -0
  104. package/{lib → dist}/index.js +4 -1
  105. package/dist/index.js.map +1 -0
  106. package/{lib → dist}/properties/ArrayProperty.d.ts +1 -0
  107. package/dist/properties/ArrayProperty.d.ts.map +1 -0
  108. package/{lib → dist}/properties/ArrayProperty.js +5 -4
  109. package/dist/properties/ArrayProperty.js.map +1 -0
  110. package/{lib → dist}/properties/BaseProperty.d.ts +3 -2
  111. package/dist/properties/BaseProperty.d.ts.map +1 -0
  112. package/{lib → dist}/properties/BaseProperty.js +18 -11
  113. package/dist/properties/BaseProperty.js.map +1 -0
  114. package/{lib → dist}/properties/BooleanProperty.d.ts +1 -0
  115. package/dist/properties/BooleanProperty.d.ts.map +1 -0
  116. package/{lib → dist}/properties/BooleanProperty.js +2 -1
  117. package/dist/properties/BooleanProperty.js.map +1 -0
  118. package/{lib → dist}/properties/CollectionProperty.d.ts +1 -0
  119. package/dist/properties/CollectionProperty.d.ts.map +1 -0
  120. package/{lib → dist}/properties/CollectionProperty.js +6 -4
  121. package/dist/properties/CollectionProperty.js.map +1 -0
  122. package/{lib → dist}/properties/DateTimeProperty.d.ts +1 -0
  123. package/dist/properties/DateTimeProperty.d.ts.map +1 -0
  124. package/{lib → dist}/properties/DateTimeProperty.js +12 -5
  125. package/dist/properties/DateTimeProperty.js.map +1 -0
  126. package/{lib → dist}/properties/EnumProperty.d.ts +1 -0
  127. package/dist/properties/EnumProperty.d.ts.map +1 -0
  128. package/{lib → dist}/properties/EnumProperty.js +4 -3
  129. package/dist/properties/EnumProperty.js.map +1 -0
  130. package/{lib → dist}/properties/FileProperty.d.ts +1 -0
  131. package/dist/properties/FileProperty.d.ts.map +1 -0
  132. package/{lib → dist}/properties/FileProperty.js +3 -2
  133. package/dist/properties/FileProperty.js.map +1 -0
  134. package/{lib → dist}/properties/HashProperty.d.ts +2 -7
  135. package/dist/properties/HashProperty.d.ts.map +1 -0
  136. package/{lib → dist}/properties/HashProperty.js +15 -23
  137. package/dist/properties/HashProperty.js.map +1 -0
  138. package/{lib → dist}/properties/MapProperty.d.ts +1 -0
  139. package/dist/properties/MapProperty.d.ts.map +1 -0
  140. package/{lib → dist}/properties/MapProperty.js +2 -1
  141. package/dist/properties/MapProperty.js.map +1 -0
  142. package/{lib → dist}/properties/NumberProperty.d.ts +1 -0
  143. package/dist/properties/NumberProperty.d.ts.map +1 -0
  144. package/{lib → dist}/properties/NumberProperty.js +15 -14
  145. package/dist/properties/NumberProperty.js.map +1 -0
  146. package/{lib → dist}/properties/ObjectProperty.d.ts +1 -0
  147. package/dist/properties/ObjectProperty.d.ts.map +1 -0
  148. package/{lib → dist}/properties/ObjectProperty.js +4 -3
  149. package/dist/properties/ObjectProperty.js.map +1 -0
  150. package/{lib → dist}/properties/Property.d.ts +1 -0
  151. package/dist/properties/Property.d.ts.map +1 -0
  152. package/{lib → dist}/properties/Property.js +12 -11
  153. package/dist/properties/Property.js.map +1 -0
  154. package/{lib → dist}/properties/StringProperty.d.ts +3 -5
  155. package/dist/properties/StringProperty.d.ts.map +1 -0
  156. package/{lib → dist}/properties/StringProperty.js +20 -28
  157. package/dist/properties/StringProperty.js.map +1 -0
  158. package/{lib → dist}/properties/index.d.ts +4 -2
  159. package/dist/properties/index.d.ts.map +1 -0
  160. package/{lib → dist}/properties/index.js +1 -0
  161. package/dist/properties/index.js.map +1 -0
  162. package/{lib → dist}/properties/types/AbstractPropertyType.d.ts +1 -0
  163. package/dist/properties/types/AbstractPropertyType.d.ts.map +1 -0
  164. package/{lib → dist}/properties/types/AbstractPropertyType.js +1 -0
  165. package/dist/properties/types/AbstractPropertyType.js.map +1 -0
  166. package/{lib → dist}/properties/types/PropertyClassType.d.ts +1 -0
  167. package/dist/properties/types/PropertyClassType.d.ts.map +1 -0
  168. package/{lib → dist}/properties/types/PropertyClassType.js +1 -0
  169. package/dist/properties/types/PropertyClassType.js.map +1 -0
  170. package/{lib → dist}/properties/types/PropertyHTMLType.d.ts +1 -0
  171. package/dist/properties/types/PropertyHTMLType.d.ts.map +1 -0
  172. package/{lib → dist}/properties/types/PropertyHTMLType.js +1 -2
  173. package/dist/properties/types/PropertyHTMLType.js.map +1 -0
  174. package/{lib → dist}/properties/types/PropertyTypes.d.ts +1 -0
  175. package/dist/properties/types/PropertyTypes.d.ts.map +1 -0
  176. package/{lib → dist}/properties/types/PropertyTypes.js +1 -0
  177. package/dist/properties/types/PropertyTypes.js.map +1 -0
  178. package/package.json +47 -46
  179. package/src/Core.ts +145 -0
  180. package/src/common/DataGenerator.ts +81 -0
  181. package/src/common/ResourcesErrors.ts +17 -0
  182. package/src/common/statuses.ts +20 -0
  183. package/src/components/AbstractObject.ts +71 -0
  184. package/src/components/BaseObject.ts +123 -0
  185. package/src/components/BaseObjectProperties.ts +65 -0
  186. package/src/components/DataObject.ts +418 -0
  187. package/src/components/Entity.ts +38 -0
  188. package/src/components/ObjectUri.test.ts +74 -0
  189. package/src/components/ObjectUri.ts +174 -0
  190. package/src/components/User.ts +111 -0
  191. package/src/components/index.ts +19 -0
  192. package/src/components/types/AbstractObjectClass.ts +7 -0
  193. package/src/components/types/BaseObjectClass.ts +8 -0
  194. package/src/components/types/BaseObjectType.ts +10 -0
  195. package/src/components/types/DataObjectClass.ts +27 -0
  196. package/src/components/types/DataObjectParams.ts +8 -0
  197. package/src/components/types/DataObjectType.ts +27 -0
  198. package/src/components/types/EntityClass.ts +3 -0
  199. package/src/components/types/Payload.ts +11 -0
  200. package/src/components/types/Persisted.ts +7 -0
  201. package/src/components/types/Properties.ts +1 -0
  202. package/src/components/types/ProxyConstructor.ts +13 -0
  203. package/src/components/types/toJSONParams.ts +12 -0
  204. package/src/index.ts +97 -0
  205. package/src/properties/ArrayProperty.test.ts +46 -0
  206. package/src/properties/ArrayProperty.ts +87 -0
  207. package/src/properties/BaseProperty.test.ts +79 -0
  208. package/src/properties/BaseProperty.ts +140 -0
  209. package/src/properties/BooleanProperty.ts +11 -0
  210. package/src/properties/CollectionProperty.test.ts +22 -0
  211. package/src/properties/CollectionProperty.ts +43 -0
  212. package/src/properties/DateTimeProperty.ts +47 -0
  213. package/src/properties/EnumProperty.ts +36 -0
  214. package/src/properties/FileProperty.ts +14 -0
  215. package/src/properties/HashProperty.test.ts +108 -0
  216. package/src/properties/HashProperty.ts +70 -0
  217. package/src/properties/MapProperty.ts +19 -0
  218. package/src/properties/NumberProperty.test.ts +38 -0
  219. package/src/properties/NumberProperty.ts +110 -0
  220. package/src/properties/ObjectProperty.ts +118 -0
  221. package/src/properties/Property.ts +85 -0
  222. package/src/properties/StringProperty.test.ts +46 -0
  223. package/src/properties/StringProperty.ts +121 -0
  224. package/src/properties/index.ts +62 -0
  225. package/src/properties/types/AbstractPropertyType.ts +8 -0
  226. package/src/properties/types/PropertyClassType.ts +11 -0
  227. package/src/properties/types/PropertyHTMLType.ts +23 -0
  228. package/src/properties/types/PropertyTypes.ts +13 -0
  229. package/lib/Core.js +0 -133
  230. package/lib/components/BaseObject.js +0 -103
  231. package/lib/components/BaseObjectProperties.d.ts +0 -1
  232. package/lib/components/Entity.js +0 -71
  233. package/lib/components/types/Properties.d.ts +0 -3
  234. package/lib/components/types/Properties.js +0 -1
@@ -0,0 +1,123 @@
1
+ import { ObjectUri } from './ObjectUri'
2
+ import { DataObjectClass } from './types/DataObjectClass'
3
+ import { DataObject } from './DataObject'
4
+ import { BaseObjectType } from './types/BaseObjectType'
5
+ import { BaseObjectProperties } from './BaseObjectProperties'
6
+ import { AbstractObject } from './AbstractObject'
7
+ import { DataObjectType } from './types/DataObjectType'
8
+
9
+ export class BaseObject extends AbstractObject {
10
+ // implements BaseObjectClass {
11
+ static PROPS_DEFINITION: any /*DataObjectProperties*/ = BaseObjectProperties
12
+
13
+ static getProperty(key: string) {
14
+ return BaseObject.PROPS_DEFINITION.find((prop: any) => prop.name === key)
15
+ }
16
+
17
+ static fillProperties(child: any = this) {
18
+ // merge base properties with additional or redefined ones
19
+ const base = [...BaseObject.PROPS_DEFINITION]
20
+
21
+ child.PROPS_DEFINITION.forEach((property: any) => {
22
+ // manage parent properties potential redeclaration
23
+ const found = base.findIndex((el: any) => el.name === property.name)
24
+ if (found !== -1) {
25
+ base[found] = property
26
+ } else {
27
+ base.push(property)
28
+ }
29
+ })
30
+
31
+ const dao = DataObject.factory({
32
+ properties: base,
33
+ parentProp: this.PARENT_PROP,
34
+ })
35
+ dao.uri.class = child
36
+
37
+ return dao
38
+ }
39
+
40
+ static async daoFactory(
41
+ src: string | ObjectUri | DataObjectType | undefined = undefined,
42
+ child: any = this
43
+ ): Promise<DataObjectType> {
44
+ const dao = this.fillProperties(child)
45
+
46
+ return dao
47
+ }
48
+
49
+ /**
50
+ * Instantiates from an object
51
+ * @param src
52
+ * @param child
53
+ * @returns
54
+ */
55
+ static fromObject<T extends BaseObjectType>(src: T, child: any = this): any {
56
+ const dao = this.fillProperties(child)
57
+
58
+ dao.uri = new ObjectUri(
59
+ `${this.COLLECTION}${ObjectUri.DEFAULT}`,
60
+ Reflect.get(src, 'name')
61
+ )
62
+
63
+ dao.uri.class = child
64
+
65
+ dao.populateFromData(src as any)
66
+
67
+ const obj = new this(dao)
68
+
69
+ return obj
70
+ }
71
+
72
+ static async factory(
73
+ src: string | ObjectUri | BaseObjectType | undefined = undefined,
74
+ child: any = this
75
+ ): Promise<any> {
76
+ try {
77
+ if (typeof src == 'object' && !(src instanceof ObjectUri)) {
78
+ return this.fromObject(src)
79
+ }
80
+
81
+ const dao = await this.daoFactory(src, child)
82
+
83
+ const constructedObject = Reflect.construct(this, [dao])
84
+
85
+ return constructedObject
86
+ } catch (err) {
87
+ throw new Error(
88
+ `Unable to build instance for '${this.name}': ${
89
+ (err as Error).message
90
+ }`
91
+ )
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Fetches an object from its backend path
97
+ * @param path
98
+ * @returns
99
+ */
100
+ static async fromBackend<T>(path: string): Promise<T> {
101
+ if (!path.includes('/')) {
102
+ return this.factory(`${this.COLLECTION}/${path}`)
103
+ }
104
+ return this.factory(path)
105
+ }
106
+
107
+ /**
108
+ * Instantiates from a DataObject
109
+ * @param dao
110
+ * @returns
111
+ */
112
+ static fromDataObject<T extends BaseObjectType>(
113
+ dao: DataObjectClass<any>
114
+ ): any {
115
+ const obj = new this(dao)
116
+
117
+ return obj //.toProxy()
118
+ }
119
+
120
+ asReference() {
121
+ return this._dataObject.toReference()
122
+ }
123
+ }
@@ -0,0 +1,65 @@
1
+ import * as statuses from '../common/statuses'
2
+ import { StringProperty } from '../properties/StringProperty'
3
+ import { ObjectProperty } from '../properties/ObjectProperty'
4
+ import { EnumProperty } from '../properties/EnumProperty'
5
+ import { DateTimeProperty } from '../properties/DateTimeProperty'
6
+ import * as htmlType from '../properties/types/PropertyHTMLType'
7
+
8
+ export const BaseObjectProperties: any = [
9
+ {
10
+ name: 'name',
11
+ mandatory: true,
12
+ type: StringProperty.TYPE,
13
+ minLength: 1,
14
+ maxLength: 100,
15
+ fullSearch: true,
16
+ htmlType: htmlType.NAME,
17
+ },
18
+ {
19
+ name: 'status',
20
+ mandatory: true,
21
+ type: EnumProperty.TYPE,
22
+ values: [
23
+ statuses.CREATED,
24
+ statuses.PENDING,
25
+ statuses.ACTIVE,
26
+ statuses.DELETED,
27
+ ],
28
+ defaultValue: statuses.CREATED,
29
+ },
30
+ // the following properties may be optionally
31
+ // populated with a backend middleware
32
+ {
33
+ name: 'createdBy',
34
+ type: ObjectProperty.TYPE,
35
+ instanceOf: 'User',
36
+ mandatory: true,
37
+ protected: true,
38
+ },
39
+ {
40
+ name: 'createdAt',
41
+ type: DateTimeProperty.TYPE,
42
+ mandatory: true,
43
+ protected: true,
44
+ },
45
+ {
46
+ name: 'updatedBy',
47
+ type: ObjectProperty.TYPE,
48
+ instanceOf: 'User',
49
+ },
50
+ {
51
+ name: 'updatedAt',
52
+ type: DateTimeProperty.TYPE,
53
+ },
54
+ {
55
+ name: 'deletedBy',
56
+ type: ObjectProperty.TYPE,
57
+ instanceOf: 'User',
58
+ protected: true,
59
+ },
60
+ {
61
+ name: 'deletedAt',
62
+ type: DateTimeProperty.TYPE,
63
+ protected: true,
64
+ },
65
+ ]
@@ -0,0 +1,418 @@
1
+ import { Property } from '../properties/Property'
2
+ import { PropertyClassType } from '../properties/types/PropertyClassType'
3
+ import { AbstractObject } from './AbstractObject'
4
+ import { ObjectUri } from './ObjectUri'
5
+ import { NotFoundError } from '../common/ResourcesErrors'
6
+ import { toJSONParams } from './types/toJSONParams'
7
+ import { BaseObject } from './BaseObject'
8
+ import { DataObjectType } from './types/DataObjectType'
9
+ import { DataObjectParams } from './types/DataObjectParams'
10
+
11
+ export type CoreObject<T extends AbstractObject> = T
12
+
13
+ export type Properties = { [x: string]: PropertyClassType }
14
+
15
+ export interface DataObjectFactoryType {
16
+ path: string
17
+ [x: string]: any
18
+ }
19
+
20
+ /**
21
+ * Data objects constitute the agnostic glue between objects and backends.
22
+ * They handle data and identifiers in a protected registry
23
+ * This is what backends and objects manipulate, oblivious of the other.
24
+ */
25
+ export class DataObject implements DataObjectType {
26
+ protected _objectUri: ObjectUri
27
+ protected _uid: string | undefined = undefined
28
+ protected _properties: Properties = {}
29
+ protected _populated: boolean = false
30
+ protected _parentProp: string | undefined
31
+
32
+ protected _proxied: any
33
+
34
+ /**
35
+ * Has data been modified since last backend operation?
36
+ */
37
+ protected _modified: boolean = false
38
+
39
+ /**
40
+ * Constructor is protected, use factory() instead
41
+ * @param params object of parameters
42
+ */
43
+ protected constructor(params: DataObjectParams | undefined) {
44
+ if (params) {
45
+ if (typeof params.uri !== 'object') {
46
+ this._objectUri = new ObjectUri(params.uri)
47
+ } else {
48
+ this._objectUri = params.uri
49
+ }
50
+ this._parentProp = params.parentProp
51
+ } else {
52
+ this._objectUri = new ObjectUri()
53
+ }
54
+
55
+ if (params && Array.isArray(params.properties)) {
56
+ this._init(params.properties)
57
+ }
58
+ }
59
+
60
+ protected _init(properties: any[]) {
61
+ properties.forEach((prop) => {
62
+ this._properties[prop.name] = Property.factory(prop, this)
63
+ })
64
+ }
65
+
66
+ /**
67
+ * Wrap instance into proxy to get access to properties
68
+ * @returns Proxy
69
+ */
70
+ public asProxy() {
71
+ return new Proxy(this, {
72
+ get: (target, prop) => {
73
+ return target.val(prop as string)
74
+ },
75
+ set(target, prop, newValue) {
76
+ if (prop === 'uid' || prop === 'core') {
77
+ throw new Error(`Property '${prop}' is readonly`)
78
+ }
79
+
80
+ target.set(prop as string, newValue)
81
+ return true
82
+ },
83
+ })
84
+ }
85
+
86
+ public setProperties(properties: Properties) {
87
+ // TODO check if doable
88
+ this._properties = properties
89
+ }
90
+
91
+ /**
92
+ * Return a map of all propoerties or only those matching the provided type
93
+ * @param type
94
+ * @returns
95
+ */
96
+ public getProperties(type?: string) {
97
+ if (type) {
98
+ const matches = {}
99
+ for (let k of Object.keys(this._properties)) {
100
+ if (this._properties[k].constructor.name === type) {
101
+ Reflect.set(matches, k, this._properties[k])
102
+ }
103
+ }
104
+
105
+ return matches
106
+ }
107
+
108
+ return this._properties
109
+ }
110
+
111
+ public addProperty(property: PropertyClassType) {
112
+ if (Object.keys(this._properties).includes(property.name)) {
113
+ throw new Error(`Property ${property.name} already exists`)
114
+ }
115
+ this._properties[property.name] = property
116
+ }
117
+
118
+ /**
119
+ * Populate data object from instant data or backend query
120
+ * @param data
121
+ */
122
+ async populate(
123
+ data: { name: string; [x: string]: unknown } | undefined = undefined
124
+ ): Promise<DataObject> {
125
+ if (this._populated === false) {
126
+ if (data) {
127
+ this.populateFromData(data)
128
+ // } else if (this.path !== '/' && this.path !== '') {
129
+ // await this.populateFromBackend()
130
+ }
131
+ this._populated = true
132
+
133
+ if (Reflect.get(this._properties, 'name')) {
134
+ this.uri.label = this.val('name')
135
+ }
136
+ }
137
+
138
+ return this
139
+ }
140
+
141
+ /**
142
+ * Populate data object from instant data or backend query
143
+ * @param data
144
+ */
145
+ populateFromData(data: { [x: string]: unknown }): this {
146
+ if (this._populated === false) {
147
+ for (const key in data) {
148
+ if (Reflect.get(this._properties, key)) {
149
+ const val = data[key]
150
+ if (
151
+ val &&
152
+ typeof val === 'object' &&
153
+ !val.hasOwnProperty('bucket') &&
154
+ 'ref' in val &&
155
+ typeof val.ref == 'string' &&
156
+ 'label' in val &&
157
+ typeof val.label == 'string'
158
+ ) {
159
+ const { ref, label } = val
160
+
161
+ Reflect.get(this._properties, key).set(
162
+ new ObjectUri(ref, label),
163
+ false
164
+ )
165
+ } else {
166
+ Reflect.get(this._properties, key).set(data[key], false)
167
+ }
168
+ }
169
+ }
170
+
171
+ this._populated = true
172
+
173
+ if (Reflect.get(this._properties, 'name')) {
174
+ this.uri.label = this.val('name')
175
+ }
176
+ }
177
+
178
+ return this
179
+ }
180
+
181
+ isPopulated() {
182
+ return this._populated
183
+ }
184
+
185
+ get properties(): Properties {
186
+ return this._properties
187
+ }
188
+
189
+ // get backend() {
190
+ // return this._objectUri ? this._objectUri.backend : undefined
191
+ // }
192
+
193
+ get path() {
194
+ return this._objectUri ? this._objectUri.path : ''
195
+ }
196
+
197
+ set uid(uid: string | undefined) {
198
+ if (this._uid !== undefined) {
199
+ throw new Error(`DataObject already has an uid`)
200
+ }
201
+ this._uid = uid
202
+ }
203
+
204
+ get uid(): string | undefined {
205
+ return this._objectUri ? this._objectUri.uid : undefined
206
+ }
207
+
208
+ get data(): any {
209
+ return this._properties
210
+ }
211
+
212
+ set uri(uri: ObjectUri) {
213
+ this._objectUri = uri
214
+ if (this._objectUri.collection !== ObjectUri.MISSING_COLLECTION) {
215
+ // this._persisted = true
216
+ }
217
+ }
218
+
219
+ get uri(): ObjectUri {
220
+ return this._objectUri
221
+ }
222
+
223
+ get class(): any {
224
+ // TODO get class type
225
+ return this.uri.class
226
+ }
227
+
228
+ get parentProp() {
229
+ return this._parentProp
230
+ }
231
+ set parentProp(str) {
232
+ this._parentProp = str
233
+ }
234
+
235
+ has(key: string) {
236
+ return Reflect.has(this._properties, key)
237
+ }
238
+
239
+ /**
240
+ * Returns property matching key or throw
241
+ * @param key string
242
+ * @returns BaseProperty
243
+ */
244
+ get(key: string) {
245
+ if (!Reflect.has(this._properties, key)) {
246
+ throw new NotFoundError(`No property matching key '${key}'`)
247
+ }
248
+ return Reflect.get(this._properties, key)
249
+ }
250
+
251
+ set(key: string, val: any) {
252
+ if (!this.has(key)) {
253
+ throw new Error(`Unknown property in data object: ${key}`)
254
+ }
255
+ this._properties[key].set(val)
256
+ this._populated = true
257
+ this._modified = true
258
+
259
+ return this
260
+ }
261
+
262
+ /**
263
+ * Get value of given property
264
+ * @param key string
265
+ * @returns any
266
+ */
267
+ val(key: string, transform: string | undefined = undefined) {
268
+ if (this.has(key)) {
269
+ return Reflect.get(this._properties, key).val(transform)
270
+ } else {
271
+ return undefined
272
+ }
273
+ }
274
+
275
+ toJSON(params: boolean | toJSONParams = false): { [x: string]: any } {
276
+ let objectsAsReferences: boolean = false,
277
+ withoutURIData: boolean = false,
278
+ ignoreUnchanged: boolean = false,
279
+ ignoreNulls: boolean = false,
280
+ converters: any = {}
281
+
282
+ if (typeof params === 'object') {
283
+ // Any missing parameter should resolve to false
284
+ objectsAsReferences = Boolean(params.objectsAsReferences)
285
+ withoutURIData = Boolean(params.withoutURIData)
286
+ ignoreUnchanged = Boolean(params.ignoreUnchanged)
287
+ ignoreNulls = Boolean(params.ignoreNulls)
288
+ converters = params.converters
289
+ }
290
+
291
+ return {
292
+ ...(!withoutURIData &&
293
+ this.uri && { uid: this.uri.uid, path: this.uri.path }),
294
+ ...this._dataToJSON(
295
+ objectsAsReferences,
296
+ ignoreUnchanged,
297
+ ignoreNulls,
298
+ converters
299
+ ),
300
+ }
301
+ }
302
+
303
+ toReference() {
304
+ return {
305
+ ...this._objectUri.toReference(),
306
+ label: this.val('name') || '',
307
+ }
308
+ }
309
+
310
+ protected _dataToJSON(
311
+ objectsAsReferences = false,
312
+ ignoreUnchanged = false,
313
+ ignoreNulls = false,
314
+ converters = {}
315
+ ) {
316
+ const data = {}
317
+ Object.keys(this._properties).forEach((key: string) => {
318
+ const prop = Reflect.get(this._properties, key)
319
+ if (ignoreNulls && (prop.val() === null || prop.val() === undefined))
320
+ return
321
+ if (ignoreUnchanged && prop.hasChanged === false) return
322
+
323
+ switch (prop.constructor.name) {
324
+ case 'CollectionProperty':
325
+ // ignore
326
+ break
327
+ case 'ObjectProperty':
328
+ const value: BaseObject | ObjectUri | undefined = prop.val()
329
+ Reflect.set(
330
+ data,
331
+ key,
332
+ value
333
+ ? objectsAsReferences && !(value instanceof ObjectUri)
334
+ ? value.asReference()
335
+ : value.toJSON
336
+ ? value.toJSON()
337
+ : value
338
+ : null
339
+ )
340
+
341
+ break
342
+
343
+ case 'BooleanProperty':
344
+ Reflect.set(data, key, Boolean(prop.val()))
345
+ break
346
+
347
+ case 'ArrayProperty':
348
+ Reflect.set(data, key, prop.val() || [])
349
+ break
350
+
351
+ case 'DateTimeProperty':
352
+ Reflect.set(
353
+ data,
354
+ key,
355
+ prop.val(Reflect.get(converters, 'datetime')) || null
356
+ )
357
+ break
358
+
359
+ default:
360
+ Reflect.set(data, key, prop.val() || null)
361
+ break
362
+ }
363
+ })
364
+
365
+ return data
366
+ }
367
+
368
+ // async read(): Promise<DataObjectClass<any>> {
369
+ // throw new Error(
370
+ // `This is just a stub, please use DataObject from @quatrain/backend to persist`
371
+ // )
372
+ // }
373
+
374
+ // save(): Promise<DataObjectClass<any>> {
375
+ // throw new Error(
376
+ // `This is just a stub, please use DataObject from @quatrain/backend to persist`
377
+ // )
378
+ // }
379
+
380
+ // async delete(): Promise<DataObjectClass<any>> {
381
+ // throw new Error(
382
+ // `This is just a stub, please use DataObject from @quatrain/backend to persist`
383
+ // )
384
+ // }
385
+
386
+ /**
387
+ * Data object must be created from factory in order for async-loaded data to be available
388
+ * @param className
389
+ * @param param
390
+ * @returns DataObject
391
+ */
392
+ static factory(param: DataObjectParams | undefined = undefined): DataObject {
393
+ try {
394
+ return new this(param)
395
+ } catch (err) {
396
+ console.log(err)
397
+ throw new Error(
398
+ `Unable to build data object: ${(err as Error).message}`
399
+ )
400
+ }
401
+ }
402
+
403
+ async clone(data: any = {}): Promise<DataObject> {
404
+ const cloned = await DataObject.factory()
405
+ cloned.uri.class = this.uri.class
406
+ cloned._populated = false
407
+
408
+ for (let property of Object.keys(this._properties)) {
409
+ cloned._properties[property] = this._properties[property].clone()
410
+ }
411
+
412
+ if (data) {
413
+ await cloned.populate(data)
414
+ }
415
+
416
+ return cloned
417
+ }
418
+ }
@@ -0,0 +1,38 @@
1
+ import { BaseObject } from './BaseObject'
2
+ import { BaseObjectProperties } from './BaseObjectProperties'
3
+ //import { User } from './User'
4
+ //import { CollectionProperty } from '../properties/CollectionProperty'
5
+ import { StringProperty } from '../properties/StringProperty'
6
+ import * as htmlType from '../properties/types/PropertyHTMLType'
7
+ import { BaseObjectType } from './types/BaseObjectType'
8
+
9
+ export interface EntityType extends BaseObjectType {
10
+ // users?: User[]
11
+ }
12
+
13
+ export class Entity extends BaseObject {
14
+ static COLLECTION = 'entities'
15
+
16
+ static PROPS_DEFINITION = [
17
+ ...BaseObjectProperties,
18
+ {
19
+ // surcharge property minLength and htmlType
20
+ name: 'name',
21
+ type: StringProperty.TYPE,
22
+ mandatory: true,
23
+ minLength: 1,
24
+ htmlType: htmlType.ORG,
25
+ },
26
+ // {
27
+ // name: 'users',
28
+ // mandatory: true,
29
+ // type: CollectionProperty.TYPE,
30
+ // instanceOf: User,
31
+ // parentKey: 'entity',
32
+ // },
33
+ ]
34
+
35
+ static async factory(src: any = undefined): Promise<Entity> {
36
+ return super.factory(src, Entity)
37
+ }
38
+ }