openchs-models 1.33.7 → 1.33.9

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.
@@ -13,19 +13,20 @@ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object
13
13
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
14
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
15
  /**
16
- * Framework-level handler for embedded object safety in Realm 12+
17
- * This automatically processes embedded objects to prevent invalidation issues
16
+ * Framework-level handler for nested object safety in Realm 12+
17
+ * This automatically processes nested objects (relationships) to prevent invalidation issues
18
+ * Note: This handles ALL nested objects, not just Realm's embedded object feature
18
19
  */
19
- class RealmEmbeddedObjectHandler {
20
+ class RealmNestedObjectHandler {
20
21
  /**
21
- * Automatically processes embedded objects in a data structure
22
+ * Automatically processes nested objects in a data structure
22
23
  * This should be called by RealmProxy.create() before creating objects
23
24
  *
24
25
  * @param {Object} data - The object data to process
25
26
  * @param {Object} schema - The Realm schema for the object
26
- * @returns {Object} Processed data with safe embedded objects
27
+ * @returns {Object} Processed data with safe nested objects
27
28
  */
28
- static processEmbeddedObjects(data, schema) {
29
+ static processNestedObjects(data, schema) {
29
30
  if (!data || !schema || !schema.properties) {
30
31
  return data || {};
31
32
  }
@@ -34,23 +35,23 @@ class RealmEmbeddedObjectHandler {
34
35
  const propertySchema = schema.properties[propertyName];
35
36
  const propertyValue = data[propertyName];
36
37
 
37
- // Handle embedded objects (including optional ones)
38
- if (this.isEmbeddedObjectProperty(propertySchema) && propertyValue) {
39
- processedData[propertyName] = this.safeCopyEmbeddedObject(propertyValue);
38
+ // Handle nested objects (including optional ones)
39
+ if (this.isNestedObjectProperty(propertySchema) && propertyValue) {
40
+ processedData[propertyName] = this.safeCopyNestedObject(propertyValue);
40
41
  }
41
42
 
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);
43
+ // Handle lists with nested objects
44
+ if (this.isListOfNestedObjects(propertySchema) && Array.isArray(propertyValue)) {
45
+ processedData[propertyName] = propertyValue.map(item => item ? this.safeCopyNestedObject(item) : item);
45
46
  }
46
47
  });
47
48
  return processedData;
48
49
  }
49
50
 
50
51
  /**
51
- * Checks if a property schema defines an embedded object
52
+ * Checks if a property schema defines a nested object (relationship)
52
53
  */
53
- static isEmbeddedObjectProperty(propertySchema) {
54
+ static isNestedObjectProperty(propertySchema) {
54
55
  if (!propertySchema || propertySchema.type !== 'object') {
55
56
  return false;
56
57
  }
@@ -58,53 +59,53 @@ class RealmEmbeddedObjectHandler {
58
59
  }
59
60
 
60
61
  /**
61
- * Checks if a property schema defines a list of embedded objects
62
+ * Checks if a property schema defines a list of nested objects
62
63
  */
63
- static isListOfEmbeddedObjects(propertySchema) {
64
+ static isListOfNestedObjects(propertySchema) {
64
65
  return propertySchema && propertySchema.type === 'list' && propertySchema.objectType && propertySchema.objectType !== 'string';
65
66
  }
66
67
 
67
68
  /**
68
- * Safely copies an embedded object using the best available method
69
+ * Safely copies a nested object using the best available method
69
70
  */
70
- static safeCopyEmbeddedObject(embeddedObj) {
71
- if (!embeddedObj) {
71
+ static safeCopyNestedObject(nestedObj) {
72
+ if (!nestedObj) {
72
73
  return null;
73
74
  }
74
75
 
75
76
  // If it's not a Realm object, return as-is
76
- if (!(0, _RealmCollectionHelper.isRealmObject)(embeddedObj)) {
77
- return embeddedObj;
77
+ if (!(0, _RealmCollectionHelper.isRealmObject)(nestedObj)) {
78
+ return nestedObj;
78
79
  }
79
80
  try {
80
81
  // Method 1: Try toJSON() (convenient)
81
- if (typeof embeddedObj.toJSON === 'function') {
82
- return embeddedObj.toJSON();
82
+ if (typeof nestedObj.toJSON === 'function') {
83
+ return nestedObj.toJSON();
83
84
  }
84
85
  } catch (error) {
85
86
  // Fall back to manual copy if toJSON fails
86
87
  }
87
88
 
88
89
  // Method 2: Manual deep copy (reliable)
89
- return this.deepCopyEmbeddedObject(embeddedObj);
90
+ return this.deepCopyNestedObject(nestedObj);
90
91
  }
91
92
 
92
93
  /**
93
- * Manual deep copy of embedded object
94
+ * Manual deep copy of nested object
94
95
  */
95
- static deepCopyEmbeddedObject(embeddedObj) {
96
- if (!embeddedObj) {
96
+ static deepCopyNestedObject(nestedObj) {
97
+ if (!nestedObj) {
97
98
  return null;
98
99
  }
99
100
  const plainCopy = {};
100
101
 
101
102
  // Try to get schema properties
102
103
  try {
103
- if (embeddedObj.objectSchema && typeof embeddedObj.objectSchema === 'function') {
104
- const schema = embeddedObj.objectSchema();
104
+ if (nestedObj.objectSchema && typeof nestedObj.objectSchema === 'function') {
105
+ const schema = nestedObj.objectSchema();
105
106
  if (schema && schema.properties) {
106
107
  Object.keys(schema.properties).forEach(prop => {
107
- plainCopy[prop] = embeddedObj[prop];
108
+ plainCopy[prop] = nestedObj[prop];
108
109
  });
109
110
  return plainCopy;
110
111
  }
@@ -114,13 +115,13 @@ class RealmEmbeddedObjectHandler {
114
115
  }
115
116
 
116
117
  // Fallback: Copy all enumerable properties
117
- Object.keys(embeddedObj).forEach(prop => {
118
- if (typeof embeddedObj[prop] !== 'function') {
119
- plainCopy[prop] = embeddedObj[prop];
118
+ Object.keys(nestedObj).forEach(prop => {
119
+ if (typeof nestedObj[prop] !== 'function') {
120
+ plainCopy[prop] = nestedObj[prop];
120
121
  }
121
122
  });
122
123
  return plainCopy;
123
124
  }
124
125
  }
125
- var _default = RealmEmbeddedObjectHandler;
126
+ var _default = RealmNestedObjectHandler;
126
127
  exports.default = _default;
@@ -8,7 +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
+ var _RealmNestedObjectHandler = _interopRequireDefault(require("./RealmNestedObjectHandler"));
12
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
13
  const isVanillaArray = function (object) {
14
14
  return !_lodash.default.isNil(object) && "RealmListProxy" !== object.constructor.name && _lodash.default.isArrayLikeObject(object);
@@ -43,11 +43,12 @@ class RealmProxy {
43
43
  }
44
44
 
45
45
  /**
46
- *
47
- * @param schemaName
48
- * @param object
49
- * @param updateMode , all === true, modified , never === false
50
- * @returns {*}
46
+ * Creates a new entity in the database
47
+ *
48
+ * @param schemaName - The schema name of the entity to create
49
+ * @param object - The object data (can be entity wrapper or raw object)
50
+ * @param updateMode - Update mode: "never" (default), "modified", "all", or boolean equivalents
51
+ * @returns {*} - The created entity wrapped in its entity class
51
52
  */
52
53
  create(schemaName, object, updateMode = "never") {
53
54
  const entityClass = this.entityMappingConfig.getEntityClass(schemaName);
@@ -56,38 +57,30 @@ class RealmProxy {
56
57
  // Extract the underlying data from entity wrapper if needed
57
58
  const rawObject = (0, _RealmCollectionHelper.getUnderlyingRealmObject)(object) || object;
58
59
 
59
- // Automatically process embedded objects for Realm 12+ safety
60
- const processedObject = _RealmEmbeddedObjectHandler.default.processEmbeddedObjects(rawObject, schema);
60
+ // 🚀 FRAMEWORK-LEVEL: Automatically process nested objects for Realm 12+ safety
61
+ const processedObject = _RealmNestedObjectHandler.default.processNestedObjects(rawObject, schema);
61
62
 
62
- // Only validate properties that are truly mandatory (no optional: true AND no default value)
63
- // This maintains backward compatibility with existing data and Realm's native behavior
64
- const mandatoryObjectSchemaProperties = _lodash.default.keys(_lodash.default.pickBy(schema.properties, property => !property.optional && !property.hasOwnProperty('default')));
65
- const emptyMandatoryProperties = [];
63
+ // Lightweight validation: Check for null/undefined mandatory properties
64
+ // This provides clear error messages for debugging production issues
65
+ // Validates when:
66
+ // 1. In strict creation mode ("never" or false), OR
67
+ // 2. Touching any mandatory property (prevents setting mandatory fields to null)
68
+ const mandatoryObjectSchemaProperties = this.entityMappingConfig.getMandatoryObjectSchemaProperties(schemaName);
66
69
  const saveObjectKeys = Object.keys(processedObject);
67
70
  if (updateMode === "never" || updateMode === false || _lodash.default.intersection(mandatoryObjectSchemaProperties, saveObjectKeys).length > 0) {
68
- // Check for null/undefined mandatory properties that are present in the object
69
- saveObjectKeys.forEach(x => {
70
- const propertyValue = processedObject[x];
71
- if (_lodash.default.isNil(propertyValue) && _lodash.default.some(mandatoryObjectSchemaProperties, y => y === x)) {
72
- emptyMandatoryProperties.push(x);
71
+ const emptyMandatoryProperties = [];
72
+ saveObjectKeys.forEach(key => {
73
+ const propertyValue = processedObject[key];
74
+ if (_lodash.default.isNil(propertyValue) && _lodash.default.some(mandatoryObjectSchemaProperties, mandatoryProp => mandatoryProp === key)) {
75
+ emptyMandatoryProperties.push(key);
73
76
  }
74
77
  });
75
-
76
- // Enhanced validation: Only check for missing mandatory properties in strict update modes
77
- // or when we have some mandatory properties present (indicating intent to save a complete entity)
78
- const isStrictUpdateMode = updateMode === "never" || updateMode === false;
79
- const hasSomeMandatoryProperties = _lodash.default.intersection(mandatoryObjectSchemaProperties, saveObjectKeys).length > 0;
80
- if (isStrictUpdateMode && hasSomeMandatoryProperties) {
81
- mandatoryObjectSchemaProperties.forEach(mandatoryProp => {
82
- if (!saveObjectKeys.includes(mandatoryProp)) {
83
- emptyMandatoryProperties.push(mandatoryProp);
84
- }
85
- });
86
- }
87
78
  if (emptyMandatoryProperties.length > 0) {
88
- throw new Error(`${emptyMandatoryProperties.join(",")} are mandatory for ${schemaName}, Keys being saved - ${saveObjectKeys}. UUID: ${processedObject.uuid}`);
79
+ throw new Error(`${emptyMandatoryProperties.join(",")} are mandatory for ${schemaName}, ` + `Keys being saved - ${saveObjectKeys.join(",")}. UUID: ${processedObject.uuid}`);
89
80
  }
90
81
  }
82
+
83
+ // Let Realm handle remaining validation (types, constraints, etc.)
91
84
  const dbEntity = this.realmDb.create(schemaName, processedObject, updateMode);
92
85
  return new entityClass(dbEntity);
93
86
  }
package/dist/index.js CHANGED
@@ -315,10 +315,10 @@ Object.defineProperty(exports, "EntityMappingConfig", {
315
315
  return _Schema.default;
316
316
  }
317
317
  });
318
- Object.defineProperty(exports, "RealmEmbeddedObjectHandler", {
318
+ Object.defineProperty(exports, "RealmNestedObjectHandler", {
319
319
  enumerable: true,
320
320
  get: function () {
321
- return _RealmEmbeddedObjectHandler.default;
321
+ return _RealmNestedObjectHandler.default;
322
322
  }
323
323
  });
324
324
  Object.defineProperty(exports, "Settings", {
@@ -875,7 +875,7 @@ var _ReferenceEntity = _interopRequireDefault(require("./ReferenceEntity"));
875
875
  var _RuleDependency = _interopRequireDefault(require("./RuleDependency"));
876
876
  var _Rule = _interopRequireDefault(require("./Rule"));
877
877
  var _Schema = _interopRequireDefault(require("./Schema"));
878
- var _RealmEmbeddedObjectHandler = _interopRequireDefault(require("./framework/RealmEmbeddedObjectHandler"));
878
+ var _RealmNestedObjectHandler = _interopRequireDefault(require("./framework/RealmNestedObjectHandler"));
879
879
  var _Settings = _interopRequireDefault(require("./Settings"));
880
880
  var _SingleCodedValue = _interopRequireDefault(require("./observation/SingleCodedValue"));
881
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.7",
4
+ "version": "1.33.9",
5
5
  "private": false,
6
6
  "repository": {
7
7
  "type": "git",