openchs-models 1.33.4 → 1.33.5

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.
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _lodash = _interopRequireDefault(require("lodash"));
8
+ var _RealmCollectionHelper = require("./RealmCollectionHelper");
9
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
11
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
12
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
13
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
14
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
15
+ /**
16
+ * Framework-level handler for embedded object safety in Realm 12+
17
+ * This automatically processes embedded objects to prevent invalidation issues
18
+ */
19
+ class RealmEmbeddedObjectHandler {
20
+ /**
21
+ * Automatically processes embedded objects in a data structure
22
+ * This should be called by RealmProxy.create() before creating objects
23
+ *
24
+ * @param {Object} data - The object data to process
25
+ * @param {Object} schema - The Realm schema for the object
26
+ * @returns {Object} Processed data with safe embedded objects
27
+ */
28
+ static processEmbeddedObjects(data, schema) {
29
+ if (!data || !schema || !schema.properties) {
30
+ return data || {};
31
+ }
32
+ const processedData = _objectSpread({}, data);
33
+ Object.keys(schema.properties).forEach(propertyName => {
34
+ const propertySchema = schema.properties[propertyName];
35
+ const propertyValue = data[propertyName];
36
+
37
+ // Handle embedded objects (including optional ones)
38
+ if (this.isEmbeddedObjectProperty(propertySchema) && propertyValue) {
39
+ processedData[propertyName] = this.safeCopyEmbeddedObject(propertyValue);
40
+ }
41
+
42
+ // Handle lists with embedded objects
43
+ if (this.isListOfEmbeddedObjects(propertySchema) && Array.isArray(propertyValue)) {
44
+ processedData[propertyName] = propertyValue.map(item => item ? this.safeCopyEmbeddedObject(item) : item);
45
+ }
46
+ });
47
+ return processedData;
48
+ }
49
+
50
+ /**
51
+ * Checks if a property schema defines an embedded object
52
+ */
53
+ static isEmbeddedObjectProperty(propertySchema) {
54
+ if (!propertySchema || propertySchema.type !== 'object') {
55
+ return false;
56
+ }
57
+ return !!(propertySchema.objectType && propertySchema.objectType !== 'string');
58
+ }
59
+
60
+ /**
61
+ * Checks if a property schema defines a list of embedded objects
62
+ */
63
+ static isListOfEmbeddedObjects(propertySchema) {
64
+ return propertySchema && propertySchema.type === 'list' && propertySchema.objectType && propertySchema.objectType !== 'string';
65
+ }
66
+
67
+ /**
68
+ * Safely copies an embedded object using the best available method
69
+ */
70
+ static safeCopyEmbeddedObject(embeddedObj) {
71
+ if (!embeddedObj) {
72
+ return null;
73
+ }
74
+
75
+ // If it's not a Realm object, return as-is
76
+ if (!(0, _RealmCollectionHelper.isRealmObject)(embeddedObj)) {
77
+ return embeddedObj;
78
+ }
79
+ try {
80
+ // Method 1: Try toJSON() (convenient)
81
+ if (typeof embeddedObj.toJSON === 'function') {
82
+ return embeddedObj.toJSON();
83
+ }
84
+ } catch (error) {
85
+ // Fall back to manual copy if toJSON fails
86
+ }
87
+
88
+ // Method 2: Manual deep copy (reliable)
89
+ return this.deepCopyEmbeddedObject(embeddedObj);
90
+ }
91
+
92
+ /**
93
+ * Manual deep copy of embedded object
94
+ */
95
+ static deepCopyEmbeddedObject(embeddedObj) {
96
+ if (!embeddedObj) {
97
+ return null;
98
+ }
99
+ const plainCopy = {};
100
+
101
+ // Try to get schema properties
102
+ try {
103
+ if (embeddedObj.objectSchema && typeof embeddedObj.objectSchema === 'function') {
104
+ const schema = embeddedObj.objectSchema();
105
+ if (schema && schema.properties) {
106
+ Object.keys(schema.properties).forEach(prop => {
107
+ plainCopy[prop] = embeddedObj[prop];
108
+ });
109
+ return plainCopy;
110
+ }
111
+ }
112
+ } catch (error) {
113
+ // Fall back to enumerable properties
114
+ }
115
+
116
+ // Fallback: Copy all enumerable properties
117
+ Object.keys(embeddedObj).forEach(prop => {
118
+ if (typeof embeddedObj[prop] !== 'function') {
119
+ plainCopy[prop] = embeddedObj[prop];
120
+ }
121
+ });
122
+ return plainCopy;
123
+ }
124
+ }
125
+ var _default = RealmEmbeddedObjectHandler;
126
+ exports.default = _default;
@@ -8,6 +8,7 @@ var _RealmResultsProxy = _interopRequireDefault(require("./RealmResultsProxy"));
8
8
  var _lodash = _interopRequireDefault(require("lodash"));
9
9
  var _RealmCollectionHelper = require("./RealmCollectionHelper");
10
10
  var _General = _interopRequireDefault(require("../utility/General"));
11
+ var _RealmEmbeddedObjectHandler = _interopRequireDefault(require("./RealmEmbeddedObjectHandler"));
11
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
13
  const isVanillaArray = function (object) {
13
14
  return !_lodash.default.isNil(object) && "RealmListProxy" !== object.constructor.name && _lodash.default.isArrayLikeObject(object);
@@ -44,26 +45,30 @@ class RealmProxy {
44
45
  /**
45
46
  *
46
47
  * @param schemaName
47
- * @param properties
48
+ * @param object
48
49
  * @param updateMode , all === true, modified , never === false
49
50
  * @returns {*}
50
51
  */
51
- create(schemaName, properties, updateMode = "never") {
52
- const underlyingObject = _lodash.default.isNil(properties.that) ? properties : properties.that;
52
+ create(schemaName, object, updateMode = "never") {
53
53
  const entityClass = this.entityMappingConfig.getEntityClass(schemaName);
54
- const mandatoryObjectSchemaProperties = this.entityMappingConfig.getMandatoryObjectSchemaProperties(schemaName);
54
+ const underlyingObject = (0, _RealmCollectionHelper.getUnderlyingRealmObject)(object);
55
+ const schema = entityClass.schema;
56
+
57
+ // 🚀 FRAMEWORK-LEVEL: Automatically process embedded objects for Realm 12+ safety
58
+ const processedObject = _RealmEmbeddedObjectHandler.default.processEmbeddedObjects(underlyingObject, schema);
59
+ const mandatoryObjectSchemaProperties = _lodash.default.keys(_lodash.default.pickBy(schema.properties, property => !property.optional));
55
60
  const emptyMandatoryProperties = [];
56
- const saveObjectKeys = Object.keys(underlyingObject);
61
+ const saveObjectKeys = Object.keys(processedObject);
57
62
  if (updateMode === "never" || updateMode === false || _lodash.default.intersection(mandatoryObjectSchemaProperties, saveObjectKeys).length > 0) {
58
63
  saveObjectKeys.forEach(x => {
59
- const propertyValue = underlyingObject[x];
64
+ const propertyValue = processedObject[x];
60
65
  if (_lodash.default.isNil(propertyValue) && _lodash.default.some(mandatoryObjectSchemaProperties, y => y === x)) emptyMandatoryProperties.push(x);
61
66
  });
62
67
  if (emptyMandatoryProperties.length > 0) {
63
- throw new Error(`${emptyMandatoryProperties.join(",")} are mandatory for ${schemaName}, Keys being saved - ${saveObjectKeys}. UUID: ${underlyingObject.uuid}`);
68
+ throw new Error(`${emptyMandatoryProperties.join(",")} are mandatory for ${schemaName}, Keys being saved - ${saveObjectKeys}. UUID: ${processedObject.uuid}`);
64
69
  }
65
70
  }
66
- const dbEntity = this.realmDb.create(schemaName, underlyingObject, updateMode);
71
+ const dbEntity = this.realmDb.create(schemaName, processedObject, updateMode);
67
72
  return new entityClass(dbEntity);
68
73
  }
69
74
  delete(object) {
package/dist/index.js CHANGED
@@ -315,6 +315,12 @@ Object.defineProperty(exports, "EntityMappingConfig", {
315
315
  return _Schema.default;
316
316
  }
317
317
  });
318
+ Object.defineProperty(exports, "RealmEmbeddedObjectHandler", {
319
+ enumerable: true,
320
+ get: function () {
321
+ return _RealmEmbeddedObjectHandler.default;
322
+ }
323
+ });
318
324
  Object.defineProperty(exports, "Settings", {
319
325
  enumerable: true,
320
326
  get: function () {
@@ -869,6 +875,7 @@ var _ReferenceEntity = _interopRequireDefault(require("./ReferenceEntity"));
869
875
  var _RuleDependency = _interopRequireDefault(require("./RuleDependency"));
870
876
  var _Rule = _interopRequireDefault(require("./Rule"));
871
877
  var _Schema = _interopRequireDefault(require("./Schema"));
878
+ var _RealmEmbeddedObjectHandler = _interopRequireDefault(require("./framework/RealmEmbeddedObjectHandler"));
872
879
  var _Settings = _interopRequireDefault(require("./Settings"));
873
880
  var _SingleCodedValue = _interopRequireDefault(require("./observation/SingleCodedValue"));
874
881
  var _SingleSelectFilter = _interopRequireDefault(require("./application/SingleSelectFilter"));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "openchs-models",
3
3
  "description": "OpenCHS data model to be used by front end clients",
4
- "version": "1.33.4",
4
+ "version": "1.33.5",
5
5
  "private": false,
6
6
  "repository": {
7
7
  "type": "git",