breeze-client 2.2.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (299) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +83 -63
  3. package/adapters/abstract-data-service-adapter.d.ts +120 -0
  4. package/adapters/abstract-data-service-adapter.js +395 -0
  5. package/adapters/abstract-data-service-adapter.js.map +1 -0
  6. package/adapters/adapter-ajax-fetch.d.ts +12 -0
  7. package/adapters/adapter-ajax-fetch.js +13 -0
  8. package/adapters/adapter-ajax-fetch.js.map +1 -0
  9. package/{adapter-ajax-post → adapters}/adapter-ajax-post.d.ts +40 -36
  10. package/{fesm2022/breeze-client-adapter-ajax-post.mjs → adapters/adapter-ajax-post.js} +80 -82
  11. package/adapters/adapter-ajax-post.js.map +1 -0
  12. package/{adapter-ajax-fetch → adapters}/adapter-core.d.ts +4 -4
  13. package/{fesm2022/breeze-client-adapter-uri-builder-json.mjs → adapters/adapter-core.js} +48 -91
  14. package/adapters/adapter-core.js.map +1 -0
  15. package/adapters/adapter-data-service-webapi.d.ts +9 -0
  16. package/{fesm2022/breeze-client-adapter-data-service-webapi.mjs → adapters/adapter-data-service-webapi.js} +105 -107
  17. package/adapters/adapter-data-service-webapi.js.map +1 -0
  18. package/adapters/adapter-model-library-backing-store.d.ts +32 -0
  19. package/adapters/adapter-model-library-backing-store.js +321 -0
  20. package/adapters/adapter-model-library-backing-store.js.map +1 -0
  21. package/adapters/adapter-uri-builder-json.d.ts +11 -0
  22. package/adapters/adapter-uri-builder-json.js +40 -0
  23. package/adapters/adapter-uri-builder-json.js.map +1 -0
  24. package/adapters/http.d.ts +52 -0
  25. package/adapters/http.js +202 -0
  26. package/adapters/http.js.map +1 -0
  27. package/angular/adapter-angular-httpclient.d.ts +21 -0
  28. package/angular/adapter-angular-httpclient.js +70 -0
  29. package/angular/adapter-angular-httpclient.js.map +1 -0
  30. package/breeze.d.ts +215 -0
  31. package/breeze.js +141 -0
  32. package/breeze.js.map +1 -0
  33. package/config/config.d.ts +212 -0
  34. package/config/config.js +392 -0
  35. package/config/config.js.map +1 -0
  36. package/config/configure.d.ts +66 -0
  37. package/config/configure.js +46 -0
  38. package/config/configure.js.map +1 -0
  39. package/config/default-adapters.d.ts +1 -0
  40. package/config/default-adapters.js +40 -0
  41. package/config/default-adapters.js.map +1 -0
  42. package/config/interface-registry.d.ts +191 -0
  43. package/config/interface-registry.js +5 -0
  44. package/config/interface-registry.js.map +1 -0
  45. package/{src → core}/assert-param.d.ts +52 -60
  46. package/core/assert-param.js +390 -0
  47. package/core/assert-param.js.map +1 -0
  48. package/core/core.d.ts +285 -0
  49. package/core/core.js +772 -0
  50. package/core/core.js.map +1 -0
  51. package/core/enum.d.ts +116 -0
  52. package/core/enum.js +167 -0
  53. package/core/enum.js.map +1 -0
  54. package/core/event.d.ts +169 -0
  55. package/core/event.js +338 -0
  56. package/core/event.js.map +1 -0
  57. package/entity/array.d.ts +3 -0
  58. package/entity/array.js +4 -0
  59. package/entity/array.js.map +1 -0
  60. package/entity/complex-array.d.ts +17 -0
  61. package/entity/complex-array.js +104 -0
  62. package/entity/complex-array.js.map +1 -0
  63. package/entity/default-property-interceptor.d.ts +1 -0
  64. package/entity/default-property-interceptor.js +496 -0
  65. package/entity/default-property-interceptor.js.map +1 -0
  66. package/{src → entity}/entity-action.d.ts +36 -42
  67. package/entity/entity-action.js +45 -0
  68. package/entity/entity-action.js.map +1 -0
  69. package/entity/entity-aspect.d.ts +457 -0
  70. package/entity/entity-aspect.js +1262 -0
  71. package/entity/entity-aspect.js.map +1 -0
  72. package/entity/entity-base.d.ts +55 -0
  73. package/entity/entity-base.js +41 -0
  74. package/entity/entity-base.js.map +1 -0
  75. package/entity/entity-group.d.ts +1 -0
  76. package/entity/entity-group.js +224 -0
  77. package/entity/entity-group.js.map +1 -0
  78. package/entity/entity-key.d.ts +95 -0
  79. package/entity/entity-key.js +189 -0
  80. package/entity/entity-key.js.map +1 -0
  81. package/{src → entity}/entity-state.d.ts +112 -84
  82. package/entity/entity-state.js +135 -0
  83. package/entity/entity-state.js.map +1 -0
  84. package/entity/key-generator.d.ts +57 -0
  85. package/entity/key-generator.js +155 -0
  86. package/entity/key-generator.js.map +1 -0
  87. package/entity/observable-array.d.ts +25 -0
  88. package/entity/observable-array.js +230 -0
  89. package/entity/observable-array.js.map +1 -0
  90. package/entity/primitive-array.d.ts +12 -0
  91. package/entity/primitive-array.js +71 -0
  92. package/entity/primitive-array.js.map +1 -0
  93. package/entity/relation-array.d.ts +24 -0
  94. package/entity/relation-array.js +176 -0
  95. package/entity/relation-array.js.map +1 -0
  96. package/entity/unattached-children-map.d.ts +1 -0
  97. package/entity/unattached-children-map.js +105 -0
  98. package/entity/unattached-children-map.js.map +1 -0
  99. package/generate-entity-classes.js +1176 -0
  100. package/manager/entity-manager.d.ts +801 -0
  101. package/manager/entity-manager.js +2395 -0
  102. package/manager/entity-manager.js.map +1 -0
  103. package/{src → manager}/save-options.d.ts +48 -42
  104. package/manager/save-options.js +51 -0
  105. package/manager/save-options.js.map +1 -0
  106. package/{src → metadata}/data-service.d.ts +229 -184
  107. package/metadata/data-service.js +246 -0
  108. package/metadata/data-service.js.map +1 -0
  109. package/metadata/data-type.d.ts +122 -0
  110. package/metadata/data-type.js +465 -0
  111. package/metadata/data-type.js.map +1 -0
  112. package/metadata/entity-metadata.d.ts +1193 -0
  113. package/metadata/entity-metadata.js +2502 -0
  114. package/metadata/entity-metadata.js.map +1 -0
  115. package/{src → metadata}/local-query-comparison-options.d.ts +65 -59
  116. package/metadata/local-query-comparison-options.js +69 -0
  117. package/metadata/local-query-comparison-options.js.map +1 -0
  118. package/{src → metadata}/naming-convention.d.ts +75 -72
  119. package/metadata/naming-convention.js +97 -0
  120. package/metadata/naming-convention.js.map +1 -0
  121. package/mixins/mixin-get-entity-graph.d.ts +63 -0
  122. package/{fesm2022/breeze-client-mixin-get-entity-graph.mjs → mixins/mixin-get-entity-graph.js} +331 -253
  123. package/mixins/mixin-get-entity-graph.js.map +1 -0
  124. package/mixins/mixin-save-queuing.d.ts +98 -0
  125. package/{fesm2022/breeze-client-mixin-save-queuing.mjs → mixins/mixin-save-queuing.js} +493 -365
  126. package/mixins/mixin-save-queuing.js.map +1 -0
  127. package/package.json +63 -94
  128. package/query/entity-query.d.ts +521 -0
  129. package/query/entity-query.js +1149 -0
  130. package/query/entity-query.js.map +1 -0
  131. package/{src → query}/mapping-context.d.ts +44 -46
  132. package/query/mapping-context.js +412 -0
  133. package/query/mapping-context.js.map +1 -0
  134. package/query/predicate.d.ts +394 -0
  135. package/query/predicate.js +1294 -0
  136. package/query/predicate.js.map +1 -0
  137. package/query/property-path.d.ts +252 -0
  138. package/query/property-path.js +2 -0
  139. package/query/property-path.js.map +1 -0
  140. package/{src → query}/query-options.d.ts +143 -119
  141. package/query/query-options.js +180 -0
  142. package/query/query-options.js.map +1 -0
  143. package/rxjs/breeze-rxjs.d.ts +72 -0
  144. package/rxjs/breeze-rxjs.js +117 -0
  145. package/rxjs/breeze-rxjs.js.map +1 -0
  146. package/validation/validate.d.ts +583 -0
  147. package/validation/validate.js +961 -0
  148. package/validation/validate.js.map +1 -0
  149. package/{src → validation}/validation-options.d.ts +67 -63
  150. package/validation/validation-options.js +70 -0
  151. package/validation/validation-options.js.map +1 -0
  152. package/adapter-ajax-angularjs/adapter-ajax-angularjs.d.ts +0 -17
  153. package/adapter-ajax-angularjs/adapter-core.d.ts +0 -4
  154. package/adapter-ajax-angularjs/index.d.ts +0 -5
  155. package/adapter-ajax-fetch/adapter-ajax-fetch.d.ts +0 -18
  156. package/adapter-ajax-fetch/index.d.ts +0 -5
  157. package/adapter-ajax-httpclient/adapter-ajax-httpclient.d.ts +0 -13
  158. package/adapter-ajax-httpclient/adapter-core.d.ts +0 -4
  159. package/adapter-ajax-httpclient/index.d.ts +0 -5
  160. package/adapter-ajax-jquery/adapter-ajax-jquery.d.ts +0 -15
  161. package/adapter-ajax-jquery/index.d.ts +0 -5
  162. package/adapter-ajax-post/index.d.ts +0 -5
  163. package/adapter-data-service-odata/adapter-core.d.ts +0 -4
  164. package/adapter-data-service-odata/adapter-data-service-odata.d.ts +0 -17
  165. package/adapter-data-service-odata/index.d.ts +0 -5
  166. package/adapter-data-service-webapi/adapter-data-service-webapi.d.ts +0 -15
  167. package/adapter-data-service-webapi/index.d.ts +0 -5
  168. package/adapter-model-library-backing-store/adapter-model-library-backing-store.d.ts +0 -10
  169. package/adapter-model-library-backing-store/index.d.ts +0 -5
  170. package/adapter-model-library-ko/adapter-model-library-ko.d.ts +0 -10
  171. package/adapter-model-library-ko/index.d.ts +0 -5
  172. package/adapter-uri-builder-json/adapter-core.d.ts +0 -4
  173. package/adapter-uri-builder-json/adapter-uri-builder-json.d.ts +0 -8
  174. package/adapter-uri-builder-json/index.d.ts +0 -5
  175. package/adapter-uri-builder-odata/adapter-core.d.ts +0 -4
  176. package/adapter-uri-builder-odata/adapter-uri-builder-odata.d.ts +0 -8
  177. package/adapter-uri-builder-odata/index.d.ts +0 -5
  178. package/esm2022/adapter-ajax-angularjs/adapter-ajax-angularjs.mjs +0 -135
  179. package/esm2022/adapter-ajax-angularjs/adapter-core.mjs +0 -49
  180. package/esm2022/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.mjs +0 -5
  181. package/esm2022/adapter-ajax-fetch/adapter-ajax-fetch.mjs +0 -135
  182. package/esm2022/adapter-ajax-fetch/adapter-core.mjs +0 -49
  183. package/esm2022/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.mjs +0 -5
  184. package/esm2022/adapter-ajax-httpclient/adapter-ajax-httpclient.mjs +0 -139
  185. package/esm2022/adapter-ajax-httpclient/adapter-core.mjs +0 -49
  186. package/esm2022/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.mjs +0 -5
  187. package/esm2022/adapter-ajax-jquery/adapter-ajax-jquery.mjs +0 -107
  188. package/esm2022/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.mjs +0 -5
  189. package/esm2022/adapter-ajax-post/adapter-ajax-post.mjs +0 -77
  190. package/esm2022/adapter-ajax-post/breeze-client-adapter-ajax-post.mjs +0 -5
  191. package/esm2022/adapter-data-service-odata/adapter-core.mjs +0 -49
  192. package/esm2022/adapter-data-service-odata/adapter-data-service-odata.mjs +0 -461
  193. package/esm2022/adapter-data-service-odata/breeze-client-adapter-data-service-odata.mjs +0 -5
  194. package/esm2022/adapter-data-service-webapi/adapter-data-service-webapi.mjs +0 -100
  195. package/esm2022/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.mjs +0 -5
  196. package/esm2022/adapter-model-library-backing-store/adapter-model-library-backing-store.mjs +0 -269
  197. package/esm2022/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.mjs +0 -5
  198. package/esm2022/adapter-model-library-ko/adapter-model-library-ko.mjs +0 -241
  199. package/esm2022/adapter-model-library-ko/breeze-client-adapter-model-library-ko.mjs +0 -5
  200. package/esm2022/adapter-uri-builder-json/adapter-core.mjs +0 -49
  201. package/esm2022/adapter-uri-builder-json/adapter-uri-builder-json.mjs +0 -37
  202. package/esm2022/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.mjs +0 -5
  203. package/esm2022/adapter-uri-builder-odata/adapter-core.mjs +0 -49
  204. package/esm2022/adapter-uri-builder-odata/adapter-uri-builder-odata.mjs +0 -191
  205. package/esm2022/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.mjs +0 -5
  206. package/esm2022/breeze-client.mjs +0 -5
  207. package/esm2022/index.mjs +0 -2
  208. package/esm2022/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.mjs +0 -5
  209. package/esm2022/mixin-get-entity-graph/mixin-get-entity-graph.mjs +0 -269
  210. package/esm2022/mixin-save-queuing/breeze-client-mixin-save-queuing.mjs +0 -5
  211. package/esm2022/mixin-save-queuing/mixin-save-queuing.mjs +0 -421
  212. package/esm2022/src/abstract-data-service-adapter.mjs +0 -325
  213. package/esm2022/src/array.mjs +0 -4
  214. package/esm2022/src/assert-param.mjs +0 -330
  215. package/esm2022/src/breeze.mjs +0 -85
  216. package/esm2022/src/complex-array.mjs +0 -117
  217. package/esm2022/src/config.mjs +0 -232
  218. package/esm2022/src/core.mjs +0 -712
  219. package/esm2022/src/csdl-metadata-parser.mjs +0 -385
  220. package/esm2022/src/data-service.mjs +0 -221
  221. package/esm2022/src/data-type.mjs +0 -510
  222. package/esm2022/src/default-property-interceptor.mjs +0 -460
  223. package/esm2022/src/entity-action.mjs +0 -45
  224. package/esm2022/src/entity-aspect.mjs +0 -897
  225. package/esm2022/src/entity-group.mjs +0 -192
  226. package/esm2022/src/entity-key.mjs +0 -125
  227. package/esm2022/src/entity-manager.mjs +0 -2163
  228. package/esm2022/src/entity-metadata.mjs +0 -2242
  229. package/esm2022/src/entity-query.mjs +0 -1024
  230. package/esm2022/src/entity-state.mjs +0 -107
  231. package/esm2022/src/enum.mjs +0 -143
  232. package/esm2022/src/event.mjs +0 -264
  233. package/esm2022/src/interface-registry.mjs +0 -39
  234. package/esm2022/src/key-generator.mjs +0 -110
  235. package/esm2022/src/local-query-comparison-options.mjs +0 -65
  236. package/esm2022/src/mapping-context.mjs +0 -411
  237. package/esm2022/src/naming-convention.mjs +0 -92
  238. package/esm2022/src/observable-array.mjs +0 -183
  239. package/esm2022/src/predicate.mjs +0 -1259
  240. package/esm2022/src/primitive-array.mjs +0 -85
  241. package/esm2022/src/query-options.mjs +0 -152
  242. package/esm2022/src/relation-array.mjs +0 -173
  243. package/esm2022/src/save-options.mjs +0 -41
  244. package/esm2022/src/unattached-children-map.mjs +0 -56
  245. package/esm2022/src/validate.mjs +0 -995
  246. package/esm2022/src/validation-options.mjs +0 -64
  247. package/fesm2022/breeze-client-adapter-ajax-angularjs.mjs +0 -190
  248. package/fesm2022/breeze-client-adapter-ajax-angularjs.mjs.map +0 -1
  249. package/fesm2022/breeze-client-adapter-ajax-fetch.mjs +0 -190
  250. package/fesm2022/breeze-client-adapter-ajax-fetch.mjs.map +0 -1
  251. package/fesm2022/breeze-client-adapter-ajax-httpclient.mjs +0 -194
  252. package/fesm2022/breeze-client-adapter-ajax-httpclient.mjs.map +0 -1
  253. package/fesm2022/breeze-client-adapter-ajax-jquery.mjs +0 -114
  254. package/fesm2022/breeze-client-adapter-ajax-jquery.mjs.map +0 -1
  255. package/fesm2022/breeze-client-adapter-ajax-post.mjs.map +0 -1
  256. package/fesm2022/breeze-client-adapter-data-service-odata.mjs +0 -516
  257. package/fesm2022/breeze-client-adapter-data-service-odata.mjs.map +0 -1
  258. package/fesm2022/breeze-client-adapter-data-service-webapi.mjs.map +0 -1
  259. package/fesm2022/breeze-client-adapter-model-library-backing-store.mjs +0 -276
  260. package/fesm2022/breeze-client-adapter-model-library-backing-store.mjs.map +0 -1
  261. package/fesm2022/breeze-client-adapter-model-library-ko.mjs +0 -248
  262. package/fesm2022/breeze-client-adapter-model-library-ko.mjs.map +0 -1
  263. package/fesm2022/breeze-client-adapter-uri-builder-json.mjs.map +0 -1
  264. package/fesm2022/breeze-client-adapter-uri-builder-odata.mjs +0 -246
  265. package/fesm2022/breeze-client-adapter-uri-builder-odata.mjs.map +0 -1
  266. package/fesm2022/breeze-client-mixin-get-entity-graph.mjs.map +0 -1
  267. package/fesm2022/breeze-client-mixin-save-queuing.mjs.map +0 -1
  268. package/fesm2022/breeze-client.mjs +0 -14144
  269. package/fesm2022/breeze-client.mjs.map +0 -1
  270. package/index.d.ts +0 -1
  271. package/mixin-get-entity-graph/index.d.ts +0 -5
  272. package/mixin-get-entity-graph/mixin-get-entity-graph.d.ts +0 -31
  273. package/mixin-save-queuing/index.d.ts +0 -5
  274. package/mixin-save-queuing/mixin-save-queuing.d.ts +0 -32
  275. package/src/abstract-data-service-adapter.d.ts +0 -84
  276. package/src/array.d.ts +0 -3
  277. package/src/breeze.d.ts +0 -139
  278. package/src/complex-array.d.ts +0 -13
  279. package/src/config.d.ts +0 -104
  280. package/src/core.d.ts +0 -164
  281. package/src/csdl-metadata-parser.d.ts +0 -7
  282. package/src/data-type.d.ts +0 -89
  283. package/src/default-property-interceptor.d.ts +0 -4
  284. package/src/entity-aspect.d.ts +0 -332
  285. package/src/entity-group.d.ts +0 -28
  286. package/src/entity-key.d.ts +0 -77
  287. package/src/entity-manager.d.ts +0 -680
  288. package/src/entity-metadata.d.ts +0 -988
  289. package/src/entity-query.d.ts +0 -444
  290. package/src/enum.d.ts +0 -100
  291. package/src/event.d.ts +0 -142
  292. package/src/interface-registry.d.ts +0 -150
  293. package/src/key-generator.d.ts +0 -12
  294. package/src/observable-array.d.ts +0 -52
  295. package/src/predicate.d.ts +0 -376
  296. package/src/primitive-array.d.ts +0 -7
  297. package/src/relation-array.d.ts +0 -18
  298. package/src/unattached-children-map.d.ts +0 -19
  299. package/src/validate.d.ts +0 -650
@@ -0,0 +1,496 @@
1
+ import { core } from '../core/core.js';
2
+ import { EntityKey } from './entity-key.js';
3
+ import { EntityAspect, peekProperty } from './entity-aspect.js';
4
+ import { EntityState } from './entity-state.js';
5
+ import { EntityAction } from './entity-action.js';
6
+ import { EntityQuery } from '../query/entity-query.js';
7
+ import { observableArray } from './observable-array.js';
8
+ /** @hidden @internal */
9
+ export function defaultPropertyInterceptor(property, newValue, rawAccessorFn) {
10
+ // 'this' is the entity itself in this context.
11
+ if (newValue === undefined)
12
+ newValue = null; // remove? to allow assignment to undefined in Babel constructors?
13
+ let oldValue = rawAccessorFn();
14
+ let dataType = property.dataType;
15
+ if (dataType && dataType.parse) {
16
+ // attempts to coerce a value to the correct type - if this fails return the value unchanged
17
+ if (Array.isArray(newValue) && !property.isScalar) {
18
+ newValue = newValue.map(function (nv) {
19
+ return dataType.parse(nv, typeof nv);
20
+ });
21
+ }
22
+ else {
23
+ newValue = dataType.parse(newValue, typeof newValue);
24
+ }
25
+ }
26
+ // exit if no change - extra cruft is because dateTimes don't compare cleanly.
27
+ if (newValue === oldValue || (newValue === null && oldValue === undefined) ||
28
+ (dataType && dataType.normalize && newValue && oldValue && dataType.normalize(newValue) === dataType.normalize(oldValue))) {
29
+ return;
30
+ }
31
+ // CANNOT DO NEXT LINE because it has the possibility of creating a new property
32
+ // 'entityAspect' on 'this'. - Not permitted by IE inside of a defined property on a prototype.
33
+ // let entityAspect = new EntityAspect(this);
34
+ let propertyName;
35
+ let entityAspect = this.entityAspect;
36
+ if (entityAspect) {
37
+ propertyName = property.name;
38
+ }
39
+ else {
40
+ let localAspect = this.complexAspect;
41
+ if (localAspect) {
42
+ entityAspect = localAspect.getEntityAspect();
43
+ propertyName = localAspect.getPropertyPath(property.name);
44
+ }
45
+ else {
46
+ // does not yet have an EntityAspect so just set the prop
47
+ rawAccessorFn(newValue);
48
+ return;
49
+ }
50
+ }
51
+ // Note that we need to handle multiple properties in process, not just one in order to avoid recursion.
52
+ // ( except in the case of null propagation with fks where null -> 0 in some cases.)
53
+ // (this may not be needed because of the newValue === oldValue test above)
54
+ let inProcess = entityAspect._inProcess = entityAspect._inProcess || [];
55
+ // check for recursion
56
+ if (inProcess.indexOf(property) >= 0)
57
+ return;
58
+ inProcess.push(property);
59
+ try {
60
+ let context = {
61
+ parent: this,
62
+ property: property,
63
+ newValue: newValue,
64
+ oldValue: oldValue,
65
+ propertyName: propertyName,
66
+ entityAspect: entityAspect
67
+ };
68
+ if (property.isComplexProperty) {
69
+ setDpValueComplex(context, rawAccessorFn);
70
+ }
71
+ else if (property.isDataProperty) {
72
+ setDpValueSimple(context, rawAccessorFn);
73
+ }
74
+ else {
75
+ setNpValue(context, rawAccessorFn);
76
+ }
77
+ postChangeEvents(context);
78
+ }
79
+ finally {
80
+ inProcess.pop();
81
+ }
82
+ }
83
+ function setDpValueSimple(context, rawAccessorFn) {
84
+ let parent = context.parent;
85
+ let property = context.property;
86
+ let entityAspect = context.entityAspect;
87
+ let oldValue = context.oldValue;
88
+ let newValue = context.newValue;
89
+ let entityManager = entityAspect.entityManager;
90
+ if (!property.isScalar) {
91
+ throw new Error("Nonscalar data properties are readonly - items may be added or removed but the collection may not be changed.");
92
+ }
93
+ // store an original value for this property if not already set
94
+ if (entityAspect.entityState.isUnchangedOrModified()) {
95
+ let propName = property.name;
96
+ // localAspect is not the same as entityAspect for complex props
97
+ let localAspect = EntityAspect.isEntity(parent) ? parent.entityAspect : parent.complexAspect;
98
+ if (localAspect.originalValues[propName] === undefined) {
99
+ // otherwise this entry will be skipped during serialization
100
+ localAspect.originalValues[propName] = oldValue !== undefined ? oldValue : property.defaultValue;
101
+ }
102
+ }
103
+ // if we are changing the key update our internal entityGroup indexes.
104
+ if (property.isPartOfKey && entityManager && !entityManager.isLoading) {
105
+ // 'entityType' on the next line be null for complex properties but it will only be ref'd within this
106
+ // fn when the property is part of the key
107
+ let entityType = parent.entityType;
108
+ let keyProps = entityType.keyProperties;
109
+ let values = keyProps.map(function (p) {
110
+ if (p === property) {
111
+ return newValue;
112
+ }
113
+ else {
114
+ return parent.getProperty(p.name);
115
+ }
116
+ });
117
+ let newKey = new EntityKey(entityType, values);
118
+ if (entityManager.getEntityByKey(newKey)) {
119
+ throw new Error("An entity with this key is already in the cache: " + newKey.toString());
120
+ }
121
+ let oldKey = parent.entityAspect.getKey();
122
+ let eg = entityManager._findEntityGroup(entityType); // parent is attached, so its group exists
123
+ eg._replaceKey(oldKey, newKey);
124
+ }
125
+ // process related updates ( the inverse relationship) first so that collection dups check works properly.
126
+ // update inverse relationship
127
+ let relatedNavProp = property.relatedNavigationProperty;
128
+ if (relatedNavProp && entityManager) {
129
+ // Example: bidirectional fkDataProperty: 1->n: order -> orderDetails
130
+ // orderDetail.orderId <- newOrderId || null
131
+ // ==> orderDetail.order = lookupOrder(newOrderId)
132
+ // ==> (see set navProp above)
133
+ // and
134
+ // Example: bidirectional fkDataProperty: 1->1: order -> internationalOrder
135
+ // internationalOrder.orderId <- newOrderId || null
136
+ // ==> internationalOrder.order = lookupOrder(newOrderId)
137
+ // ==> (see set navProp above)
138
+ if (newValue != null) {
139
+ let relatedEntity = null;
140
+ let key;
141
+ if (relatedNavProp.invForeignKeyNames.length) {
142
+ // property is related by field which is not the PK
143
+ const query = new EntityQuery(relatedNavProp.entityType.defaultResourceName).where(relatedNavProp.invForeignKeyNames[0], 'eq', newValue);
144
+ const qresult = entityManager.executeQueryLocally(query);
145
+ if (qresult.length === 1) {
146
+ relatedEntity = qresult[0];
147
+ }
148
+ }
149
+ else {
150
+ // property is related by the PK
151
+ key = new EntityKey(relatedNavProp.entityType, [newValue]);
152
+ relatedEntity = entityManager.getEntityByKey(key);
153
+ }
154
+ if (relatedEntity) {
155
+ parent.setProperty(relatedNavProp.name, relatedEntity);
156
+ }
157
+ else {
158
+ // it may not have been fetched yet in which case we want to add it as an unattachedChild.
159
+ if (key) {
160
+ // TODO currently _linkRelatedentities only works with PK relations, so we only add those.
161
+ entityManager._unattachedChildrenMap.addChild(key, relatedNavProp, parent);
162
+ }
163
+ parent.setProperty(relatedNavProp.name, null);
164
+ }
165
+ }
166
+ else {
167
+ parent.setProperty(relatedNavProp.name, null);
168
+ }
169
+ }
170
+ else if (property.inverseNavigationProperty && entityManager && !entityManager._inKeyFixup) {
171
+ // Example: unidirectional fkDataProperty: 1->n: region -> territories
172
+ // territory.regionId <- newRegionId
173
+ // ==> lookupRegion(newRegionId).territories.push(territory)
174
+ // and
175
+ // Example: unidirectional fkDataProperty: 1->1: order -> internationalOrder
176
+ // internationalOrder.orderId <- newOrderId
177
+ // ==> lookupOrder(newOrderId).internationalOrder = internationalOrder
178
+ // and
179
+ // Example: unidirectional fkDataProperty: 1->n: region -> territories
180
+ // territory.regionId <- null
181
+ // ==> lookupRegion(territory.oldRegionId).territories.remove(oldTerritory);
182
+ // and
183
+ // Example: unidirectional fkDataProperty: 1->1: order -> internationalOrder
184
+ // internationalOrder.orderId <- null
185
+ // ==> lookupOrder(internationalOrder.oldOrderId).internationalOrder = null;
186
+ let invNavProp = property.inverseNavigationProperty;
187
+ if (oldValue != null) {
188
+ let key = new EntityKey(invNavProp.parentType, [oldValue]);
189
+ let relatedEntity = entityManager.getEntityByKey(key);
190
+ if (relatedEntity) {
191
+ if (invNavProp.isScalar) {
192
+ relatedEntity.setProperty(invNavProp.name, null);
193
+ }
194
+ else {
195
+ // remove 'this' from old related nav prop. A collection that was never read holds
196
+ // nothing to remove, so peek rather than create one to splice nothing out of.
197
+ let relatedArray = peekProperty(relatedEntity, invNavProp.name);
198
+ if (relatedArray && !observableArray.isClearing(relatedArray)) {
199
+ // The index has to be checked: `splice(-1, 1)` removes the LAST element, so a parent
200
+ // whose collection was never fully loaded would lose an unrelated child.
201
+ const ix = relatedArray.indexOf(parent);
202
+ if (ix !== -1) {
203
+ relatedArray.splice(ix, 1);
204
+ }
205
+ }
206
+ }
207
+ }
208
+ }
209
+ if (newValue != null) {
210
+ let key = new EntityKey(invNavProp.parentType, [newValue]);
211
+ let relatedEntity = entityManager.getEntityByKey(key);
212
+ if (relatedEntity) {
213
+ if (invNavProp.isScalar) {
214
+ relatedEntity.setProperty(invNavProp.name, parent);
215
+ }
216
+ else {
217
+ relatedEntity.getProperty(invNavProp.name).push(parent);
218
+ }
219
+ }
220
+ else {
221
+ // it may not have been fetched yet in which case we want to add it as an unattachedChild.
222
+ entityManager._unattachedChildrenMap.addChild(key, invNavProp, parent);
223
+ }
224
+ }
225
+ }
226
+ rawAccessorFn(newValue);
227
+ updateStateAndValidate(context);
228
+ // if (property.isPartOfKey && (!this.complexAspect)) {
229
+ if (property.isPartOfKey) {
230
+ // propogate pk change to all related entities;
231
+ let entityType = parent.entityType;
232
+ let propertyIx = entityType.keyProperties.indexOf(property);
233
+ // this part handles order.orderId => orderDetail.orderId
234
+ // but won't handle product.productId => orderDetail.productId because product
235
+ // doesn't have an orderDetails property.
236
+ entityType.navigationProperties.forEach(function (np) {
237
+ let inverseNp = np.inverse;
238
+ let fkNames = inverseNp ? inverseNp.foreignKeyNames : np.invForeignKeyNames;
239
+ if (fkNames.length === 0)
240
+ return;
241
+ // Peek for collections: an entity whose collection has never been read has no children to
242
+ // propagate the new key to, and this runs on every key assignment - including the temporary
243
+ // key generated for every entity created.
244
+ let npValue = np.isScalar ? parent.getProperty(np.name) : peekProperty(parent, np.name);
245
+ if (!npValue)
246
+ return;
247
+ let fkName = fkNames[propertyIx];
248
+ if (np.isScalar) {
249
+ npValue.setProperty(fkName, newValue);
250
+ }
251
+ else {
252
+ npValue.slice(0).forEach(function (iv) {
253
+ iv.setProperty(fkName, newValue);
254
+ });
255
+ }
256
+ });
257
+ // this handles unidirectional problems not covered above.
258
+ if (entityManager) {
259
+ let inverseForeignKeyProperties = entityType.inverseForeignKeyProperties;
260
+ let baseEntityType = entityType.baseEntityType;
261
+ while (baseEntityType) {
262
+ inverseForeignKeyProperties = inverseForeignKeyProperties.concat(baseEntityType.inverseForeignKeyProperties);
263
+ baseEntityType = baseEntityType.baseEntityType;
264
+ }
265
+ inverseForeignKeyProperties.forEach((invFkProp) => {
266
+ if (invFkProp.relatedNavigationProperty.inverse == null) {
267
+ // this next step may be slow - it iterates over all of the entities in a group;
268
+ // hopefully it doesn't happen often.
269
+ entityManager._updateFkVal(invFkProp, oldValue, newValue);
270
+ }
271
+ });
272
+ }
273
+ // insure that cached key is updated.
274
+ entityAspect.getKey(true);
275
+ }
276
+ }
277
+ function setDpValueComplex(context, rawAccessorFn) {
278
+ let property = context.property;
279
+ let oldValue = context.oldValue;
280
+ let newValue = context.newValue;
281
+ // To get here it must be a ComplexProperty
282
+ // 'dataType' will be a complexType
283
+ let dataType = property.dataType;
284
+ if (property.isScalar) {
285
+ if (!newValue) {
286
+ throw new Error(core.formatString("You cannot set the '%1' property to null because its datatype is the ComplexType: '%2'", property.name, property.dataType.name));
287
+ }
288
+ if (!oldValue) {
289
+ let ctor = dataType.getCtor();
290
+ oldValue = new ctor();
291
+ rawAccessorFn(oldValue);
292
+ }
293
+ dataType.dataProperties.forEach(function (dp) {
294
+ let pn = dp.name;
295
+ let nv = newValue.getProperty(pn);
296
+ oldValue.setProperty(pn, nv);
297
+ });
298
+ }
299
+ else {
300
+ throw new Error(core.formatString("You cannot set the non-scalar complex property: '%1' on the type: '%2'." +
301
+ "Instead get the property and use array functions like 'push' or 'splice' to change its contents.", property.name, property.parentType.name));
302
+ }
303
+ }
304
+ function setNpValue(context, rawAccessorFn) {
305
+ let parent = context.parent;
306
+ let property = context.property;
307
+ let entityAspect = context.entityAspect;
308
+ let oldValue = context.oldValue;
309
+ let newValue = context.newValue;
310
+ if (!property.isScalar) {
311
+ throw new Error("Nonscalar navigation properties are readonly - entities can be added or removed but the collection may not be changed.");
312
+ }
313
+ let entityManager = entityAspect.entityManager;
314
+ let inverseProp = property.inverse;
315
+ // manage attachment -
316
+ if (newValue != null) {
317
+ if (!newValue.entityAspect) {
318
+ return;
319
+ }
320
+ let newAspect = newValue.entityAspect;
321
+ if (entityManager) {
322
+ if (newAspect.entityState.isDetached()) {
323
+ if (!entityManager.isLoading) {
324
+ entityManager.attachEntity(newValue, EntityState.Added);
325
+ }
326
+ }
327
+ else {
328
+ if (newAspect.entityManager !== entityManager) {
329
+ throw new Error("An Entity cannot be attached to an entity in another EntityManager. One of the two entities must be detached first.");
330
+ }
331
+ }
332
+ }
333
+ else {
334
+ if (newAspect && newAspect.entityManager) {
335
+ entityManager = newAspect.entityManager;
336
+ if (!entityManager.isLoading) {
337
+ entityManager.attachEntity(entityAspect.entity, EntityState.Added);
338
+ }
339
+ }
340
+ }
341
+ }
342
+ // process related updates ( the inverse relationship) first so that collection dups check works properly.
343
+ // update inverse relationship
344
+ if (inverseProp) {
345
+ ///
346
+ if (inverseProp.isScalar) {
347
+ // Example: bidirectional navProperty: 1->1: order -> internationalOrder
348
+ // order.internationalOrder <- internationalOrder || null
349
+ // ==> (oldInternationalOrder.order = null)
350
+ // ==> internationalOrder.order = order
351
+ if (oldValue != null) {
352
+ // TODO: null -> NullEntity later
353
+ oldValue.setProperty(inverseProp.name, null);
354
+ }
355
+ if (newValue != null) {
356
+ newValue.setProperty(inverseProp.name, parent);
357
+ }
358
+ }
359
+ else {
360
+ // Example: bidirectional navProperty: 1->n: order -> orderDetails
361
+ // orderDetail.order <- newOrder || null
362
+ // ==> (oldOrder).orderDetails.remove(orderDetail)
363
+ // ==> order.orderDetails.push(newOrder)
364
+ if (oldValue != null) {
365
+ let oldSiblings = oldValue.getProperty(inverseProp.name);
366
+ // Not while that collection is emptying itself: it removes all of its contents at once
367
+ // and publishes once for them, where splicing each child out here is O(n) per child.
368
+ if (!observableArray.isClearing(oldSiblings)) {
369
+ let ix = oldSiblings.indexOf(parent);
370
+ if (ix !== -1) {
371
+ oldSiblings.splice(ix, 1);
372
+ }
373
+ }
374
+ }
375
+ if (newValue != null) {
376
+ let siblings = newValue.getProperty(inverseProp.name);
377
+ // recursion check if already in the collection is performed by the relationArray
378
+ siblings.push(parent);
379
+ }
380
+ }
381
+ }
382
+ else if (property.invForeignKeyNames && entityManager && !entityManager._inKeyFixup) {
383
+ let invForeignKeyNames = property.invForeignKeyNames;
384
+ if (newValue != null) {
385
+ // Example: unidirectional navProperty: 1->1: order -> internationalOrder
386
+ // order.InternationalOrder <- internationalOrder
387
+ // ==> internationalOrder.orderId = orderId
388
+ // and
389
+ // Example: unidirectional navProperty: 1->n: order -> orderDetails
390
+ // orderDetail.order <-xxx newOrder
391
+ // ==> CAN'T HAPPEN because if unidirectional because orderDetail will not have an order prop
392
+ let pkValues = parent.entityAspect.getKey().values;
393
+ invForeignKeyNames.forEach((fkName, i) => {
394
+ newValue.setProperty(fkName, pkValues[i]);
395
+ });
396
+ }
397
+ else {
398
+ // Example: unidirectional navProperty: 1->1: order -> internationalOrder
399
+ // order.internationalOrder <- null
400
+ // ==> (old internationalOrder).orderId = null
401
+ // and
402
+ // Example: unidirectional navProperty: 1->n: order -> orderDetails
403
+ // orderDetail.order <-xxx newOrder
404
+ // ==> CAN'T HAPPEN because if unidirectional because orderDetail will not have an order prop
405
+ if (oldValue != null) {
406
+ invForeignKeyNames.forEach((fkName) => {
407
+ let fkProp = oldValue.entityType.getProperty(fkName);
408
+ if (!fkProp.isPartOfKey) {
409
+ // don't update with null if fk is part of the key
410
+ oldValue.setProperty(fkName, null);
411
+ }
412
+ });
413
+ }
414
+ }
415
+ }
416
+ rawAccessorFn(newValue);
417
+ updateStateAndValidate(context);
418
+ // update fk data property - this can only occur if this navProperty has
419
+ // a corresponding fk on this entity.
420
+ if (property.relatedDataProperties) {
421
+ let entityState = entityAspect.entityState;
422
+ // if either side of nav prop is detached don't clear fks. Note: oldValue in next line cannot be null so no check is needed.
423
+ if (newValue == null && (entityState.isDetached() || oldValue.entityAspect.entityState.isDetached()))
424
+ return;
425
+ if (entityState.isDeleted())
426
+ return;
427
+ // we may have inverse props indicating the related prop on the other entity, if it is not the other entity's PK
428
+ let inverseKeyProps = property.invForeignKeyNames;
429
+ if (!(inverseKeyProps && inverseKeyProps.length)) {
430
+ // otherwise, this prop is related to the other entity's PK
431
+ inverseKeyProps = property.entityType.keyProperties.map(k => k.name);
432
+ }
433
+ inverseKeyProps.forEach(function (keyProp, i) {
434
+ let relatedDataProp = property.relatedDataProperties[i];
435
+ // Do not trash related property if it is part of that entity's key
436
+ if (newValue || !relatedDataProp.isPartOfKey) {
437
+ let relatedValue = newValue ? newValue.getProperty(keyProp) : relatedDataProp.defaultValue;
438
+ parent.setProperty(relatedDataProp.name, relatedValue);
439
+ }
440
+ });
441
+ }
442
+ }
443
+ function postChangeEvents(context) {
444
+ let entityAspect = context.entityAspect;
445
+ let entityManager = entityAspect.entityManager;
446
+ let entity = entityAspect.entity;
447
+ // The argument object and the publish calls are about 11% of a tracked property set, and with
448
+ // nothing subscribed every bit of it is discarded: publish walks the _getEventParent chain via
449
+ // BreezeEvent._isEnabled before finding an empty subscriber list. Nothing inside breeze
450
+ // subscribes to either event, so for an application that does not either, that is every set.
451
+ const propertyChanged = entityAspect.propertyChanged;
452
+ if (entityManager) {
453
+ // propertyChanged will be fired during loading but we only want to fire it once per entity, not once per property.
454
+ // so propertyChanged is fired in the entityManager mergeEntity method if not fired here.
455
+ if ((!entityManager.isLoading) && (!entityManager.isRejectingChanges)) {
456
+ const entityChanged = entityManager.entityChanged;
457
+ if (!propertyChanged.hasSubscribers && !entityChanged.hasSubscribers)
458
+ return;
459
+ const propChangedArgs = makePropChangedArgs(context, entity);
460
+ propertyChanged.publish(propChangedArgs);
461
+ // don't fire entityChanged event if propertyChanged is suppressed.
462
+ entityChanged.publish({ entityAction: EntityAction.PropertyChange, entity: entity, args: propChangedArgs });
463
+ }
464
+ }
465
+ else {
466
+ if (!propertyChanged.hasSubscribers)
467
+ return;
468
+ propertyChanged.publish(makePropChangedArgs(context, entity));
469
+ }
470
+ }
471
+ function makePropChangedArgs(context, entity) {
472
+ return {
473
+ entity: entity, parent: context.parent, property: context.property,
474
+ propertyName: context.propertyName, oldValue: context.oldValue, newValue: context.newValue
475
+ };
476
+ }
477
+ function updateStateAndValidate(context) {
478
+ let entityAspect = context.entityAspect;
479
+ let entityManager = entityAspect.entityManager;
480
+ if (entityManager == null || entityManager.isLoading)
481
+ return;
482
+ let property = context.property;
483
+ if (entityAspect.entityState.isUnchanged() && !property.isUnmapped) {
484
+ entityAspect.setModified();
485
+ }
486
+ // Whatever the server, or an async validator, said about this property was about the value it had
487
+ // before this edit. Independent of validateOnPropertyChange: turning that off stops Breeze
488
+ // checking, but the old verdict is stale either way. A load returns early above, so only the
489
+ // user's edits do this.
490
+ entityAspect._clearStaleErrors(context.propertyName);
491
+ if (entityManager.validationOptions.validateOnPropertyChange) {
492
+ // entityAspect.entity is NOT the same as parent in the code below. It's use is deliberate.
493
+ entityAspect._validateProperty(context.newValue, { entity: entityAspect.entity, property: property, propertyName: context.propertyName, oldValue: context.oldValue });
494
+ }
495
+ }
496
+ //# sourceMappingURL=default-property-interceptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-property-interceptor.js","sourceRoot":"","sources":["../../src/entity/default-property-interceptor.ts"],"names":[],"mappings":"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","sourcesContent":["import { core } from '../core/core.js';\r\nimport { ComplexType, DataProperty, NavigationProperty, EntityProperty } from '../metadata/entity-metadata.js';\r\nimport { EntityKey } from './entity-key.js';\r\nimport { EntityAspect, ComplexAspect, Entity, StructuralObject, peekProperty } from './entity-aspect.js';\r\nimport { EntityState } from './entity-state.js';\r\nimport { EntityAction } from './entity-action.js';\r\nimport { EntityQuery } from '../query/entity-query.js';\r\nimport { observableArray } from './observable-array.js';\r\n\r\n/** @hidden @internal */\r\nexport function defaultPropertyInterceptor(this: StructuralObject, property: EntityProperty, newValue: any, rawAccessorFn: Function) {\r\n // 'this' is the entity itself in this context.\r\n\r\n if (newValue === undefined) newValue = null; // remove? to allow assignment to undefined in Babel constructors?\r\n let oldValue = rawAccessorFn();\r\n\r\n let dataType = (property as any).dataType;\r\n if (dataType && dataType.parse) {\r\n // attempts to coerce a value to the correct type - if this fails return the value unchanged\r\n if (Array.isArray(newValue) && !property.isScalar) {\r\n newValue = newValue.map(function (nv) {\r\n return dataType.parse(nv, typeof nv);\r\n });\r\n } else {\r\n newValue = dataType.parse(newValue, typeof newValue);\r\n }\r\n }\r\n\r\n // exit if no change - extra cruft is because dateTimes don't compare cleanly.\r\n if (newValue === oldValue || (newValue === null && oldValue === undefined) || \r\n (dataType && dataType.normalize && newValue && oldValue && dataType.normalize(newValue) === dataType.normalize(oldValue))) {\r\n return;\r\n }\r\n\r\n // CANNOT DO NEXT LINE because it has the possibility of creating a new property\r\n // 'entityAspect' on 'this'. - Not permitted by IE inside of a defined property on a prototype.\r\n // let entityAspect = new EntityAspect(this);\r\n\r\n let propertyName: string;\r\n let entityAspect = (this as any).entityAspect as EntityAspect;\r\n if (entityAspect) {\r\n propertyName = property.name;\r\n } else {\r\n let localAspect = (this as any).complexAspect as ComplexAspect;\r\n if (localAspect) {\r\n entityAspect = localAspect.getEntityAspect();\r\n propertyName = localAspect.getPropertyPath(property.name);\r\n } else {\r\n // does not yet have an EntityAspect so just set the prop\r\n rawAccessorFn(newValue);\r\n return;\r\n }\r\n }\r\n\r\n // Note that we need to handle multiple properties in process, not just one in order to avoid recursion.\r\n // ( except in the case of null propagation with fks where null -> 0 in some cases.)\r\n // (this may not be needed because of the newValue === oldValue test above)\r\n let inProcess = entityAspect._inProcess = entityAspect._inProcess || [];\r\n // check for recursion\r\n if (inProcess.indexOf(property) >= 0) return;\r\n inProcess.push(property);\r\n\r\n try {\r\n\r\n let context: IContext = {\r\n parent: this,\r\n property: property,\r\n newValue: newValue,\r\n oldValue: oldValue,\r\n propertyName: propertyName,\r\n entityAspect: entityAspect\r\n };\r\n\r\n if ((property as any).isComplexProperty) {\r\n setDpValueComplex(context, rawAccessorFn);\r\n } else if (property.isDataProperty) {\r\n setDpValueSimple(context, rawAccessorFn);\r\n } else {\r\n setNpValue(context, rawAccessorFn);\r\n }\r\n\r\n postChangeEvents(context);\r\n\r\n } finally {\r\n inProcess.pop();\r\n }\r\n}\r\n\r\ninterface IContext {\r\n parent: StructuralObject;\r\n property: EntityProperty;\r\n propertyName: string;\r\n entityAspect: EntityAspect;\r\n oldValue: any;\r\n newValue: any;\r\n}\r\n\r\nfunction setDpValueSimple(context: IContext, rawAccessorFn: any) {\r\n let parent = context.parent;\r\n let property = context.property as DataProperty;\r\n let entityAspect = context.entityAspect;\r\n let oldValue = context.oldValue;\r\n let newValue = context.newValue;\r\n\r\n let entityManager = entityAspect.entityManager;\r\n\r\n if (!property.isScalar) {\r\n throw new Error(\"Nonscalar data properties are readonly - items may be added or removed but the collection may not be changed.\");\r\n }\r\n\r\n // store an original value for this property if not already set\r\n if (entityAspect.entityState.isUnchangedOrModified()) {\r\n let propName = property.name;\r\n // localAspect is not the same as entityAspect for complex props\r\n let localAspect = EntityAspect.isEntity(parent) ? parent.entityAspect : parent.complexAspect;\r\n if (localAspect.originalValues[propName] === undefined) {\r\n // otherwise this entry will be skipped during serialization\r\n localAspect.originalValues[propName] = oldValue !== undefined ? oldValue : property.defaultValue;\r\n }\r\n }\r\n\r\n // if we are changing the key update our internal entityGroup indexes.\r\n if (property.isPartOfKey && entityManager && !entityManager.isLoading) {\r\n // 'entityType' on the next line be null for complex properties but it will only be ref'd within this\r\n // fn when the property is part of the key\r\n let entityType = (parent as Entity).entityType;\r\n let keyProps = entityType.keyProperties;\r\n let values = keyProps.map(function (p) {\r\n if (p === property) {\r\n return newValue;\r\n } else {\r\n return parent.getProperty(p.name);\r\n }\r\n });\r\n let newKey = new EntityKey(entityType, values);\r\n if (entityManager.getEntityByKey(newKey)) {\r\n throw new Error(\"An entity with this key is already in the cache: \" + newKey.toString());\r\n }\r\n let oldKey = (parent as Entity).entityAspect.getKey();\r\n let eg = entityManager._findEntityGroup(entityType)!; // parent is attached, so its group exists\r\n eg._replaceKey(oldKey, newKey);\r\n }\r\n\r\n // process related updates ( the inverse relationship) first so that collection dups check works properly.\r\n // update inverse relationship\r\n\r\n let relatedNavProp = property.relatedNavigationProperty;\r\n if (relatedNavProp && entityManager) {\r\n // Example: bidirectional fkDataProperty: 1->n: order -> orderDetails\r\n // orderDetail.orderId <- newOrderId || null\r\n // ==> orderDetail.order = lookupOrder(newOrderId)\r\n // ==> (see set navProp above)\r\n // and\r\n // Example: bidirectional fkDataProperty: 1->1: order -> internationalOrder\r\n // internationalOrder.orderId <- newOrderId || null\r\n // ==> internationalOrder.order = lookupOrder(newOrderId)\r\n // ==> (see set navProp above)\r\n\r\n if (newValue != null) {\r\n let relatedEntity: Entity | null = null;\r\n let key: EntityKey | undefined;\r\n if (relatedNavProp.invForeignKeyNames.length) {\r\n // property is related by field which is not the PK\r\n const query = new EntityQuery(relatedNavProp.entityType.defaultResourceName).where(relatedNavProp.invForeignKeyNames[0], 'eq', newValue);\r\n const qresult = entityManager.executeQueryLocally(query);\r\n if (qresult.length === 1) {\r\n relatedEntity = qresult[0];\r\n }\r\n } else {\r\n // property is related by the PK\r\n key = new EntityKey(relatedNavProp.entityType, [newValue]);\r\n relatedEntity = entityManager.getEntityByKey(key);\r\n }\r\n\r\n if (relatedEntity) {\r\n parent.setProperty(relatedNavProp.name, relatedEntity);\r\n } else {\r\n // it may not have been fetched yet in which case we want to add it as an unattachedChild.\r\n if (key) {\r\n // TODO currently _linkRelatedentities only works with PK relations, so we only add those.\r\n entityManager._unattachedChildrenMap.addChild(key, relatedNavProp, parent as Entity);\r\n }\r\n parent.setProperty(relatedNavProp.name, null);\r\n }\r\n } else {\r\n parent.setProperty(relatedNavProp.name, null);\r\n }\r\n } else if (property.inverseNavigationProperty && entityManager && !entityManager._inKeyFixup) {\r\n // Example: unidirectional fkDataProperty: 1->n: region -> territories\r\n // territory.regionId <- newRegionId\r\n // ==> lookupRegion(newRegionId).territories.push(territory)\r\n // and\r\n // Example: unidirectional fkDataProperty: 1->1: order -> internationalOrder\r\n // internationalOrder.orderId <- newOrderId\r\n // ==> lookupOrder(newOrderId).internationalOrder = internationalOrder\r\n // and\r\n // Example: unidirectional fkDataProperty: 1->n: region -> territories\r\n // territory.regionId <- null\r\n // ==> lookupRegion(territory.oldRegionId).territories.remove(oldTerritory);\r\n // and\r\n // Example: unidirectional fkDataProperty: 1->1: order -> internationalOrder\r\n // internationalOrder.orderId <- null\r\n // ==> lookupOrder(internationalOrder.oldOrderId).internationalOrder = null;\r\n\r\n let invNavProp = property.inverseNavigationProperty;\r\n\r\n if (oldValue != null) {\r\n let key = new EntityKey(invNavProp.parentType, [oldValue]);\r\n let relatedEntity = entityManager.getEntityByKey(key);\r\n if (relatedEntity) {\r\n if (invNavProp.isScalar) {\r\n relatedEntity.setProperty(invNavProp.name, null);\r\n } else {\r\n // remove 'this' from old related nav prop. A collection that was never read holds\r\n // nothing to remove, so peek rather than create one to splice nothing out of.\r\n let relatedArray = peekProperty(relatedEntity, invNavProp.name);\r\n if (relatedArray && !observableArray.isClearing(relatedArray)) {\r\n // The index has to be checked: `splice(-1, 1)` removes the LAST element, so a parent\r\n // whose collection was never fully loaded would lose an unrelated child.\r\n const ix = relatedArray.indexOf(parent);\r\n if (ix !== -1) {\r\n relatedArray.splice(ix, 1);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (newValue != null) {\r\n let key = new EntityKey(invNavProp.parentType, [newValue]);\r\n let relatedEntity = entityManager.getEntityByKey(key);\r\n\r\n if (relatedEntity) {\r\n if (invNavProp.isScalar) {\r\n relatedEntity.setProperty(invNavProp.name, parent);\r\n } else {\r\n relatedEntity.getProperty(invNavProp.name).push(parent);\r\n }\r\n } else {\r\n // it may not have been fetched yet in which case we want to add it as an unattachedChild.\r\n entityManager._unattachedChildrenMap.addChild(key, invNavProp, parent as Entity);\r\n }\r\n }\r\n\r\n }\r\n\r\n rawAccessorFn(newValue);\r\n\r\n updateStateAndValidate(context);\r\n\r\n // if (property.isPartOfKey && (!this.complexAspect)) {\r\n if (property.isPartOfKey) {\r\n // propogate pk change to all related entities;\r\n let entityType = (parent as Entity).entityType;\r\n let propertyIx = entityType.keyProperties.indexOf(property);\r\n // this part handles order.orderId => orderDetail.orderId\r\n // but won't handle product.productId => orderDetail.productId because product\r\n // doesn't have an orderDetails property.\r\n entityType.navigationProperties.forEach(function (np) {\r\n let inverseNp = np.inverse;\r\n let fkNames = inverseNp ? inverseNp.foreignKeyNames : np.invForeignKeyNames;\r\n\r\n if (fkNames.length === 0) return;\r\n // Peek for collections: an entity whose collection has never been read has no children to\r\n // propagate the new key to, and this runs on every key assignment - including the temporary\r\n // key generated for every entity created.\r\n let npValue = np.isScalar ? parent.getProperty(np.name) : peekProperty(parent, np.name);\r\n if (!npValue) return;\r\n let fkName = fkNames[propertyIx];\r\n if (np.isScalar) {\r\n npValue.setProperty(fkName, newValue);\r\n } else {\r\n npValue.slice(0).forEach(function (iv: any) {\r\n iv.setProperty(fkName, newValue);\r\n });\r\n }\r\n });\r\n // this handles unidirectional problems not covered above.\r\n if (entityManager) {\r\n let inverseForeignKeyProperties = entityType.inverseForeignKeyProperties;\r\n let baseEntityType = entityType.baseEntityType;\r\n while (baseEntityType) {\r\n inverseForeignKeyProperties = inverseForeignKeyProperties.concat(baseEntityType.inverseForeignKeyProperties);\r\n baseEntityType = baseEntityType.baseEntityType;\r\n }\r\n inverseForeignKeyProperties.forEach((invFkProp) => {\r\n if (invFkProp.relatedNavigationProperty!.inverse == null) {\r\n // this next step may be slow - it iterates over all of the entities in a group;\r\n // hopefully it doesn't happen often.\r\n entityManager!._updateFkVal(invFkProp, oldValue, newValue);\r\n }\r\n \r\n });\r\n }\r\n\r\n // insure that cached key is updated.\r\n entityAspect.getKey(true);\r\n }\r\n}\r\n\r\nfunction setDpValueComplex(context: IContext, rawAccessorFn: Function) {\r\n let property = context.property as DataProperty;\r\n let oldValue = context.oldValue;\r\n let newValue = context.newValue;\r\n\r\n // To get here it must be a ComplexProperty\r\n // 'dataType' will be a complexType\r\n let dataType = property.dataType as ComplexType;\r\n if (property.isScalar) {\r\n if (!newValue) {\r\n throw new Error(core.formatString(\"You cannot set the '%1' property to null because its datatype is the ComplexType: '%2'\", property.name, property.dataType.name));\r\n }\r\n\r\n if (!oldValue) {\r\n let ctor = dataType.getCtor();\r\n oldValue = new ctor();\r\n rawAccessorFn(oldValue);\r\n }\r\n dataType.dataProperties.forEach(function (dp) {\r\n let pn = dp.name;\r\n let nv = newValue.getProperty(pn);\r\n oldValue.setProperty(pn, nv);\r\n });\r\n } else {\r\n throw new Error(core.formatString(\"You cannot set the non-scalar complex property: '%1' on the type: '%2'.\" +\r\n \"Instead get the property and use array functions like 'push' or 'splice' to change its contents.\",\r\n property.name, property.parentType.name));\r\n }\r\n}\r\n\r\n\r\nfunction setNpValue(context: IContext, rawAccessorFn: Function) {\r\n\r\n let parent = context.parent as Entity;\r\n let property = context.property as NavigationProperty;\r\n let entityAspect = context.entityAspect;\r\n let oldValue = context.oldValue;\r\n let newValue = context.newValue;\r\n\r\n if (!property.isScalar) {\r\n throw new Error(\"Nonscalar navigation properties are readonly - entities can be added or removed but the collection may not be changed.\");\r\n }\r\n\r\n let entityManager = entityAspect.entityManager;\r\n let inverseProp = property.inverse;\r\n\r\n // manage attachment -\r\n if (newValue != null) {\r\n if (!newValue.entityAspect) {\r\n return;\r\n }\r\n let newAspect = newValue.entityAspect;\r\n if (entityManager) {\r\n if (newAspect.entityState.isDetached()) {\r\n if (!entityManager.isLoading) {\r\n entityManager.attachEntity(newValue, EntityState.Added);\r\n }\r\n } else {\r\n if (newAspect.entityManager !== entityManager) {\r\n throw new Error(\"An Entity cannot be attached to an entity in another EntityManager. One of the two entities must be detached first.\");\r\n }\r\n }\r\n } else {\r\n if (newAspect && newAspect.entityManager) {\r\n entityManager = newAspect.entityManager;\r\n if (!entityManager!.isLoading) {\r\n entityManager!.attachEntity(entityAspect.entity!, EntityState.Added);\r\n }\r\n }\r\n }\r\n }\r\n\r\n // process related updates ( the inverse relationship) first so that collection dups check works properly.\r\n // update inverse relationship\r\n if (inverseProp) {\r\n ///\r\n if (inverseProp.isScalar) {\r\n // Example: bidirectional navProperty: 1->1: order -> internationalOrder\r\n // order.internationalOrder <- internationalOrder || null\r\n // ==> (oldInternationalOrder.order = null)\r\n // ==> internationalOrder.order = order\r\n if (oldValue != null) {\r\n // TODO: null -> NullEntity later\r\n oldValue.setProperty(inverseProp.name, null);\r\n }\r\n if (newValue != null) {\r\n newValue.setProperty(inverseProp.name, parent);\r\n }\r\n } else {\r\n // Example: bidirectional navProperty: 1->n: order -> orderDetails\r\n // orderDetail.order <- newOrder || null\r\n // ==> (oldOrder).orderDetails.remove(orderDetail)\r\n // ==> order.orderDetails.push(newOrder)\r\n if (oldValue != null) {\r\n let oldSiblings = oldValue.getProperty(inverseProp.name);\r\n // Not while that collection is emptying itself: it removes all of its contents at once\r\n // and publishes once for them, where splicing each child out here is O(n) per child.\r\n if (!observableArray.isClearing(oldSiblings)) {\r\n let ix = oldSiblings.indexOf(parent);\r\n if (ix !== -1) {\r\n oldSiblings.splice(ix, 1);\r\n }\r\n }\r\n }\r\n if (newValue != null) {\r\n let siblings = newValue.getProperty(inverseProp.name);\r\n // recursion check if already in the collection is performed by the relationArray\r\n siblings.push(parent);\r\n }\r\n }\r\n } else if (property.invForeignKeyNames && entityManager && !entityManager._inKeyFixup) {\r\n let invForeignKeyNames = property.invForeignKeyNames;\r\n if (newValue != null) {\r\n // Example: unidirectional navProperty: 1->1: order -> internationalOrder\r\n // order.InternationalOrder <- internationalOrder\r\n // ==> internationalOrder.orderId = orderId\r\n // and\r\n // Example: unidirectional navProperty: 1->n: order -> orderDetails\r\n // orderDetail.order <-xxx newOrder\r\n // ==> CAN'T HAPPEN because if unidirectional because orderDetail will not have an order prop\r\n let pkValues = parent.entityAspect.getKey().values;\r\n invForeignKeyNames.forEach( (fkName, i) => {\r\n newValue!.setProperty(fkName, pkValues[i]);\r\n });\r\n } else {\r\n // Example: unidirectional navProperty: 1->1: order -> internationalOrder\r\n // order.internationalOrder <- null\r\n // ==> (old internationalOrder).orderId = null\r\n // and\r\n // Example: unidirectional navProperty: 1->n: order -> orderDetails\r\n // orderDetail.order <-xxx newOrder\r\n // ==> CAN'T HAPPEN because if unidirectional because orderDetail will not have an order prop\r\n if (oldValue != null) {\r\n invForeignKeyNames.forEach( (fkName) => {\r\n let fkProp = oldValue.entityType.getProperty(fkName);\r\n if (!fkProp.isPartOfKey) {\r\n // don't update with null if fk is part of the key\r\n oldValue.setProperty(fkName, null);\r\n }\r\n });\r\n }\r\n }\r\n }\r\n\r\n rawAccessorFn(newValue);\r\n\r\n updateStateAndValidate(context);\r\n\r\n // update fk data property - this can only occur if this navProperty has\r\n // a corresponding fk on this entity.\r\n if (property.relatedDataProperties) {\r\n let entityState = entityAspect.entityState;\r\n // if either side of nav prop is detached don't clear fks. Note: oldValue in next line cannot be null so no check is needed.\r\n if (newValue == null && (entityState.isDetached() || oldValue.entityAspect.entityState.isDetached())) return;\r\n if (entityState.isDeleted()) return;\r\n\r\n // we may have inverse props indicating the related prop on the other entity, if it is not the other entity's PK\r\n let inverseKeyProps = property.invForeignKeyNames;\r\n if (!(inverseKeyProps && inverseKeyProps.length)) {\r\n // otherwise, this prop is related to the other entity's PK\r\n inverseKeyProps = property.entityType.keyProperties.map(k => k.name);\r\n }\r\n inverseKeyProps.forEach(function (keyProp, i) {\r\n let relatedDataProp = property.relatedDataProperties[i];\r\n // Do not trash related property if it is part of that entity's key\r\n if (newValue || !relatedDataProp.isPartOfKey) {\r\n let relatedValue = newValue ? newValue.getProperty(keyProp) : relatedDataProp.defaultValue;\r\n parent.setProperty(relatedDataProp.name, relatedValue);\r\n }\r\n });\r\n }\r\n}\r\n\r\nfunction postChangeEvents(context: IContext) {\r\n let entityAspect = context.entityAspect;\r\n\r\n let entityManager = entityAspect.entityManager;\r\n let entity = entityAspect.entity;\r\n\r\n // The argument object and the publish calls are about 11% of a tracked property set, and with\r\n // nothing subscribed every bit of it is discarded: publish walks the _getEventParent chain via\r\n // BreezeEvent._isEnabled before finding an empty subscriber list. Nothing inside breeze\r\n // subscribes to either event, so for an application that does not either, that is every set.\r\n const propertyChanged = entityAspect.propertyChanged;\r\n if (entityManager) {\r\n // propertyChanged will be fired during loading but we only want to fire it once per entity, not once per property.\r\n // so propertyChanged is fired in the entityManager mergeEntity method if not fired here.\r\n if ((!entityManager.isLoading) && (!entityManager.isRejectingChanges)) {\r\n const entityChanged = entityManager.entityChanged;\r\n if (!propertyChanged.hasSubscribers && !entityChanged.hasSubscribers) return;\r\n const propChangedArgs = makePropChangedArgs(context, entity);\r\n propertyChanged.publish(propChangedArgs);\r\n // don't fire entityChanged event if propertyChanged is suppressed.\r\n entityChanged.publish({ entityAction: EntityAction.PropertyChange, entity: entity, args: propChangedArgs });\r\n }\r\n } else {\r\n if (!propertyChanged.hasSubscribers) return;\r\n propertyChanged.publish(makePropChangedArgs(context, entity));\r\n }\r\n}\r\n\r\nfunction makePropChangedArgs(context: IContext, entity: Entity | undefined) {\r\n return {\r\n entity: entity!, parent: context.parent, property: context.property,\r\n propertyName: context.propertyName, oldValue: context.oldValue, newValue: context.newValue\r\n };\r\n}\r\n\r\nfunction updateStateAndValidate(context: IContext) {\r\n let entityAspect = context.entityAspect;\r\n let entityManager = entityAspect.entityManager;\r\n if (entityManager == null || entityManager.isLoading) return;\r\n let property = context.property;\r\n\r\n if (entityAspect.entityState.isUnchanged() && !property.isUnmapped) {\r\n entityAspect.setModified();\r\n }\r\n\r\n // Whatever the server, or an async validator, said about this property was about the value it had\r\n // before this edit. Independent of validateOnPropertyChange: turning that off stops Breeze\r\n // checking, but the old verdict is stale either way. A load returns early above, so only the\r\n // user's edits do this.\r\n entityAspect._clearStaleErrors(context.propertyName);\r\n\r\n if (entityManager.validationOptions.validateOnPropertyChange) {\r\n // entityAspect.entity is NOT the same as parent in the code below. It's use is deliberate.\r\n entityAspect._validateProperty(context.newValue,\r\n { entity: entityAspect.entity, property: property, propertyName: context.propertyName, oldValue: context.oldValue });\r\n }\r\n}\r\n"]}