@yuuvis/client-core 3.7.1 → 3.8.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.
@@ -109,7 +109,7 @@ const RelationshipTypeField = {
109
109
  TARGET_ID: 'system:targetId'
110
110
  };
111
111
  const LockField = {
112
- LOCK_TAG: 'system:lock:resistent'
112
+ LOCK_TAG: 'system:lock:resistant'
113
113
  };
114
114
  const CatalogTypeField = {
115
115
  NATIVE_ID: 'system:nativeId',
@@ -2001,29 +2001,59 @@ class SystemService {
2001
2001
  * @param objectTypesQA Quick access object of all object types
2002
2002
  * @param raw If set to 'true' only the properties of the object type itself will be returned (without SOTs)
2003
2003
  */
2004
- #resolveObjectTypeFields(schemaTypeDefinition, propertiesQA, objectTypesQA) {
2005
- const objectTypeFieldIDs = schemaTypeDefinition.propertyReference.map((propertyRef) => propertyRef.value);
2004
+ #resolveObjectTypeFields(schemaTypeDefinition, propertiesQA, objectTypesQA, seen = new Set()) {
2005
+ // guard against cycles in the static-SOT or base-type chain
2006
+ if (seen.has(schemaTypeDefinition.id)) {
2007
+ return [];
2008
+ }
2009
+ seen.add(schemaTypeDefinition.id);
2010
+ // fields defined directly on the type, keeping each reference's own 'required' flag
2011
+ let fields = schemaTypeDefinition.propertyReference.flatMap((propertyRef) => {
2012
+ const propDef = propertiesQA[propertyRef.value];
2013
+ if (!propDef) {
2014
+ return [];
2015
+ }
2016
+ return [
2017
+ {
2018
+ ...propDef,
2019
+ required: propertyRef.required ?? propDef.required,
2020
+ _internalType: this.getInternalFormElementType(propDef.propertyType, propDef.classifications)
2021
+ }
2022
+ ];
2023
+ });
2024
+ // fields contributed by static secondary object types. Resolved recursively so that
2025
+ // a static SOT's own static SOTs and base fields are included too, and so each field
2026
+ // keeps the 'required' flag from the SOT's own property reference.
2006
2027
  if (schemaTypeDefinition.secondaryObjectTypeId) {
2007
2028
  schemaTypeDefinition.secondaryObjectTypeId
2008
2029
  .filter((sot) => sot.static)
2009
- .map((sot) => sot.value)
2010
- .forEach((sotID) => objectTypesQA[sotID].propertyReference.forEach((propertyRef) => objectTypeFieldIDs.push(propertyRef.value)));
2030
+ .map((sot) => objectTypesQA[sot.value])
2031
+ .filter((sotDef) => !!sotDef)
2032
+ .forEach((sotDef) => {
2033
+ fields = fields.concat(this.#resolveObjectTypeFields(sotDef, propertiesQA, objectTypesQA, seen));
2034
+ });
2011
2035
  }
2012
- let fields = objectTypeFieldIDs.map((id) => {
2013
- const propDef = propertiesQA[id];
2014
- const propRef = schemaTypeDefinition.propertyReference.find((propertyRef) => propertyRef.value === id);
2015
- const required = propRef?.required ?? propDef.required;
2016
- return {
2017
- ...propDef,
2018
- required,
2019
- _internalType: this.getInternalFormElementType(propertiesQA[id].propertyType, propertiesQA[id].classifications)
2020
- };
2021
- });
2022
- // also resolve properties of the base type
2036
+ // fields inherited from the base type
2023
2037
  if (schemaTypeDefinition.baseId !== schemaTypeDefinition.id && !!objectTypesQA[schemaTypeDefinition.baseId]) {
2024
- fields = fields.concat(this.#resolveObjectTypeFields(objectTypesQA[schemaTypeDefinition.baseId], propertiesQA, objectTypesQA));
2038
+ fields = fields.concat(this.#resolveObjectTypeFields(objectTypesQA[schemaTypeDefinition.baseId], propertiesQA, objectTypesQA, seen));
2025
2039
  }
2026
- return fields;
2040
+ // de-dupe by id, keeping the first occurrence so direct fields win over those
2041
+ // inherited from static SOTs or the base type
2042
+ return this.#dedupeFieldsById(fields);
2043
+ }
2044
+ /**
2045
+ * De-duplicate a list of fields by id, keeping the first occurrence.
2046
+ * @param fields Fields to de-duplicate
2047
+ */
2048
+ #dedupeFieldsById(fields) {
2049
+ const seen = new Set();
2050
+ return fields.filter((field) => {
2051
+ if (seen.has(field.id)) {
2052
+ return false;
2053
+ }
2054
+ seen.add(field.id);
2055
+ return true;
2056
+ });
2027
2057
  }
2028
2058
  #isCreatable(objectTypeId) {
2029
2059
  return ![SystemType.FOLDER, SystemType.DOCUMENT].includes(objectTypeId);