UNPKG

d2

Version:

Javascript library for DHIS2

625 lines (532 loc) 44 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>model/ModelDefinition.js - Documentation</title> <script src="scripts/prettify/prettify.js"></script> <script src="scripts/prettify/lang-css.js"></script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc.css"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <input type="checkbox" id="nav-trigger" class="nav-trigger" /> <label for="nav-trigger" class="navicon-button x"> <div class="navicon"></div> </label> <label for="nav-trigger" class="overlay"></label> <nav > <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="GeoFeatures.html">GeoFeatures</a></li><li></li><li><a href="module-analytics.Analytics.html">Analytics</a><ul class='methods'><li data-type='method'><a href="module-analytics.Analytics.html#.getAnalytics">getAnalytics</a></li></ul></li><li><a href="module-analytics.AnalyticsAggregate.html">AnalyticsAggregate</a><ul class='methods'><li data-type='method'><a href="module-analytics.AnalyticsAggregate.html#get">get</a></li><li data-type='method'><a href="module-analytics.AnalyticsAggregate.html#getDataValueSet">getDataValueSet</a></li><li data-type='method'><a href="module-analytics.AnalyticsAggregate.html#getDebugSql">getDebugSql</a></li><li data-type='method'><a href="module-analytics.AnalyticsAggregate.html#getRawData">getRawData</a></li></ul></li><li><a href="module-analytics.AnalyticsEvents.html">AnalyticsEvents</a><ul class='methods'><li data-type='method'><a href="module-analytics.AnalyticsEvents.html#get">get</a></li><li data-type='method'><a href="module-analytics.AnalyticsEvents.html#getAggregate">getAggregate</a></li><li data-type='method'><a href="module-analytics.AnalyticsEvents.html#getCluster">getCluster</a></li><li data-type='method'><a href="module-analytics.AnalyticsEvents.html#getCount">getCount</a></li><li data-type='method'><a href="module-analytics.AnalyticsEvents.html#getQuery">getQuery</a></li></ul></li><li><a href="module-analytics.AnalyticsRequest.html">AnalyticsRequest</a><ul class='methods'><li data-type='method'><a href="module-analytics.AnalyticsRequest.html#fromModel">fromModel</a></li></ul></li><li><a href="module-api.Api.html">Api</a><ul class='methods'><li data-type='method'><a href="module-api.Api.html#get">get</a></li><li data-type='method'><a href="module-api.Api.html#patch">patch</a></li><li data-type='method'><a href="module-api.Api.html#post">post</a></li><li data-type='method'><a href="module-api.Api.html#setBaseUrl">setBaseUrl</a></li><li data-type='method'><a href="module-api.Api.html#setDefaultHeaders">setDefaultHeaders</a></li><li data-type='method'><a href="module-api.Api.html#setUnauthorizedCallback">setUnauthorizedCallback</a></li><li data-type='method'><a href="module-api.Api.html#update">update</a></li></ul></li><li><a href="module-current-user.CurrentUser.html">CurrentUser</a><ul class='methods'><li data-type='method'><a href="module-current-user.CurrentUser.html#.create">create</a></li><li data-type='method'><a href="module-current-user.CurrentUser.html#canCreate">canCreate</a></li><li data-type='method'><a href="module-current-user.CurrentUser.html#canCreatePrivate">canCreatePrivate</a></li><li data-type='method'><a href="module-current-user.CurrentUser.html#canCreatePublic">canCreatePublic</a></li><li data-type='method'><a href="module-current-user.CurrentUser.html#canDelete">canDelete</a></li><li data-type='method'><a href="module-current-user.CurrentUser.html#canUpdate">canUpdate</a></li><li data-type='method'><a href="module-current-user.CurrentUser.html#getDataViewOrganisationUnits">getDataViewOrganisationUnits</a></li><li data-type='method'><a href="module-current-user.CurrentUser.html#getOrganisationUnits">getOrganisationUnits</a></li><li data-type='method'><a href="module-current-user.CurrentUser.html#getUserGroupIds">getUserGroupIds</a></li><li data-type='method'><a href="module-current-user.CurrentUser.html#getUserGroups">getUserGroups</a></li><li data-type='method'><a href="module-current-user.CurrentUser.html#getUserRoles">getUserRoles</a></li></ul></li><li><a href="module-current-user.UserAuthorities.html">UserAuthorities</a><ul class='methods'><li data-type='method'><a href="module-current-user.UserAuthorities.html#.create">create</a></li><li data-type='method'><a href="module-current-user.UserAuthorities.html#has">has</a></li></ul></li><li><a href="module-current-user.UserDataStore.html">UserDataStore</a><ul class='methods'><li data-type='method'><a href="module-current-user.UserDataStore.html#.getUserDataStore">getUserDataStore</a></li><li data-type='method'><a href="module-current-user.UserDataStore.html#create">create</a></li><li data-type='method'><a href="module-current-user.UserDataStore.html#delete">delete</a></li><li data-type='method'><a href="module-current-user.UserDataStore.html#get">get</a></li><li data-type='method'><a href="module-current-user.UserDataStore.html#getAll">getAll</a></li><li data-type='method'><a href="module-current-user.UserDataStore.html#has">has</a></li></ul></li><li><a href="module-current-user.UserDataStoreNamespace.html">UserDataStoreNamespace</a><ul class='methods'><li data-type='method'><a href="module-current-user.UserDataStoreNamespace.html#delete">delete</a></li><li data-type='method'><a href="module-current-user.UserDataStoreNamespace.html#get">get</a></li><li data-type='method'><a href="module-current-user.UserDataStoreNamespace.html#getKeys">getKeys</a></li><li data-type='method'><a href="module-current-user.UserDataStoreNamespace.html#set">set</a></li><li data-type='method'><a href="module-current-user.UserDataStoreNamespace.html#update">update</a></li></ul></li><li><a href="module-current-user.UserSettings.html">UserSettings</a><ul class='methods'><li data-type='method'><a href="module-current-user.UserSettings.html#all">all</a></li><li data-type='method'><a href="module-current-user.UserSettings.html#get">get</a></li><li data-type='method'><a href="module-current-user.UserSettings.html#set">set</a></li></ul></li><li><a href="module-datastore.DataStore.html">DataStore</a><ul class='methods'><li data-type='method'><a href="module-datastore.DataStore.html#.getDataStore">getDataStore</a></li><li data-type='method'><a href="module-datastore.DataStore.html#create">create</a></li><li data-type='method'><a href="module-datastore.DataStore.html#delete">delete</a></li><li data-type='method'><a href="module-datastore.DataStore.html#get">get</a></li><li data-type='method'><a href="module-datastore.DataStore.html#getAll">getAll</a></li><li data-type='method'><a href="module-datastore.DataStore.html#has">has</a></li></ul></li><li><a href="module-datastore.DataStoreNamespace.html">DataStoreNamespace</a><ul class='methods'><li data-type='method'><a href="module-datastore.DataStoreNamespace.html#delete">delete</a></li><li data-type='method'><a href="module-datastore.DataStoreNamespace.html#get">get</a></li><li data-type='method'><a href="module-datastore.DataStoreNamespace.html#getKeys">getKeys</a></li><li data-type='method'><a href="module-datastore.DataStoreNamespace.html#getMetaData">getMetaData</a></li><li data-type='method'><a href="module-datastore.DataStoreNamespace.html#set">set</a></li><li data-type='method'><a href="module-datastore.DataStoreNamespace.html#update">update</a></li></ul></li><li><a href="module-i18n-I18n.html">I18n</a><ul class='methods'><li data-type='method'><a href="module-i18n-I18n.html#.getI18n">getI18n</a></li><li data-type='method'><a href="module-i18n-I18n.html#addSource">addSource</a></li><li data-type='method'><a href="module-i18n-I18n.html#addStrings">addStrings</a></li><li data-type='method'><a href="module-i18n-I18n.html#getTranslation">getTranslation</a></li><li data-type='method'><a href="module-i18n-I18n.html#getUntranslatedStrings">getUntranslatedStrings</a></li><li data-type='method'><a href="module-i18n-I18n.html#isTranslated">isTranslated</a></li><li data-type='method'><a href="module-i18n-I18n.html#load">load</a></li></ul></li><li><a href="module-model.Filter.html">Filter</a><ul class='methods'><li data-type='method'><a href="module-model.Filter.html#.getFilter">getFilter</a></li><li data-type='method'><a href="module-model.Filter.html#equals">equals</a></li><li data-type='method'><a href="module-model.Filter.html#ilike">ilike</a></li><li data-type='method'><a href="module-model.Filter.html#in">in</a></li><li data-type='method'><a href="module-model.Filter.html#like">like</a></li><li data-type='method'><a href="module-model.Filter.html#notEqual">notEqual</a></li><li data-type='method'><a href="module-model.Filter.html#notIn">notIn</a></li><li data-type='method'><a href="module-model.Filter.html#nToken">nToken</a></li><li data-type='method'><a href="module-model.Filter.html#on">on</a></li><li data-type='method'><a href="module-model.Filter.html#operator">operator</a></li><li data-type='method'><a href="module-model.Filter.html#token">token</a></li></ul></li><li><a href="module-model.Filters.html">Filters</a><ul class='methods'><li data-type='method'><a href="module-model.Filters.html#.getFilters">getFilters</a></li><li data-type='method'><a href="module-model.Filters.html#getFilterList">getFilterList</a></li><li data-type='method'><a href="module-model.Filters.html#getFilters">getFilters</a></li><li data-type='method'><a href="module-model.Filters.html#getQueryFilterValues">getQueryFilterValues</a></li><li data-type='method'><a href="module-model.Filters.html#list">list</a></li><li data-type='method'><a href="module-model.Filters.html#logicMode">logicMode</a></li><li data-type='method'><a href="module-model.Filters.html#on">on</a></li></ul></li><li><a href="module-model.Model.html">Model</a><ul class='methods'><li data-type='method'><a href="module-model.Model.html#.create">create</a></li></ul></li><li><a href="module-model.ModelBase.html">ModelBase</a><ul class='methods'><li data-type='method'><a href="module-model.ModelBase.html#create">create</a></li><li data-type='method'><a href="module-model.ModelBase.html#delete">delete</a></li><li data-type='method'><a href="module-model.ModelBase.html#getCollectionChildren">getCollectionChildren</a></li><li data-type='method'><a href="module-model.ModelBase.html#getCollectionChildrenPropertyNames">getCollectionChildrenPropertyNames</a></li><li data-type='method'><a href="module-model.ModelBase.html#getDirtyChildren">getDirtyChildren</a></li><li data-type='method'><a href="module-model.ModelBase.html#getDirtyPropertyNames">getDirtyPropertyNames</a></li><li data-type='method'><a href="module-model.ModelBase.html#getEmbeddedObjectCollectionPropertyNames">getEmbeddedObjectCollectionPropertyNames</a></li><li data-type='method'><a href="module-model.ModelBase.html#getReferenceProperties">getReferenceProperties</a></li><li data-type='method'><a href="module-model.ModelBase.html#hasDirtyChildren">hasDirtyChildren</a></li><li data-type='method'><a href="module-model.ModelBase.html#isDirty">isDirty</a></li><li data-type='method'><a href="module-model.ModelBase.html#resetDirtyState">resetDirtyState</a></li><li data-type='method'><a href="module-model.ModelBase.html#save">save</a></li><li data-type='method'><a href="module-model.ModelBase.html#toJSON">toJSON</a></li><li data-type='method'><a href="module-model.ModelBase.html#validate">validate</a></li></ul></li><li><a href="module-model.ModelCollection.html">ModelCollection</a><ul class='methods'><li data-type='method'><a href="module-model.ModelCollection.html#add">add</a></li><li data-type='method'><a href="module-model.ModelCollection.html#clear">clear</a></li><li data-type='method'><a href="module-model.ModelCollection.html#toArray">toArray</a></li></ul></li><li><a href="module-model.ModelCollectionProperty.html">ModelCollectionProperty</a><ul class='methods'><li data-type='method'><a href="module-model.ModelCollectionProperty.html#.create">create</a></li><li data-type='method'><a href="module-model.ModelCollectionProperty.html#add">add</a></li><li data-type='method'><a href="module-model.ModelCollectionProperty.html#isDirty">isDirty</a></li><li data-type='method'><a href="module-model.ModelCollectionProperty.html#remove">remove</a></li><li data-type='method'><a href="module-model.ModelCollectionProperty.html#resetDirtyState">resetDirtyState</a></li><li data-type='method'><a href="module-model.ModelCollectionProperty.html#save">save</a></li><li data-type='method'><a href="module-model.ModelCollectionProperty.html#updateDirty">updateDirty</a></li></ul></li><li><a href="module-model.ModelDefinition.html">ModelDefinition</a><ul class='methods'><li data-type='method'><a href="module-model.ModelDefinition.html#.createFromSchema">createFromSchema</a></li><li data-type='method'><a href="module-model.ModelDefinition.html#create">create</a></li><li data-type='method'><a href="module-model.ModelDefinition.html#delete">delete</a></li><li data-type='method'><a href="module-model.ModelDefinition.html#get">get</a></li><li data-type='method'><a href="module-model.ModelDefinition.html#getOwnedPropertyNames">getOwnedPropertyNames</a></li><li data-type='method'><a href="module-model.ModelDefinition.html#getTranslatableProperties">getTranslatableProperties</a></li><li data-type='method'><a href="module-model.ModelDefinition.html#getTranslatablePropertiesWithKeys">getTranslatablePropertiesWithKeys</a></li><li data-type='method'><a href="module-model.ModelDefinition.html#isTranslatable">isTranslatable</a></li><li data-type='method'><a href="module-model.ModelDefinition.html#list">list</a></li><li data-type='method'><a href="module-model.ModelDefinition.html#save">save</a></li></ul></li><li><a href="module-model.ModelDefinitions.html">ModelDefinitions</a><ul class='methods'><li data-type='method'><a href="module-model.ModelDefinitions.html#add">add</a></li><li data-type='method'><a href="module-model.ModelDefinitions.html#mapThroughDefinitions">mapThroughDefinitions</a></li></ul></li><li><a href="module-model.ModelValidation.html">ModelValidation</a><ul class='methods'><li data-type='method'><a href="module-model.ModelValidation.html#.getModelValidation">getModelValidation</a></li><li data-type='method'><a href="module-model.ModelValidation.html#validate">validate</a></li><li data-type='method'><a href="module-model.ModelValidation.html#validateAgainstSchema">validateAgainstSchema</a></li></ul></li><li><a href="module-model.Pager.html">Pager</a><ul class='methods'><li data-type='method'><a href="module-model.Pager.html#getNextPage">getNextPage</a></li><li data-type='method'><a href="module-model.Pager.html#getPreviousPage">getPreviousPage</a></li><li data-type='method'><a href="module-model.Pager.html#goToPage">goToPage</a></li><li data-type='method'><a href="module-model.Pager.html#hasNextPage">hasNextPage</a></li><li data-type='method'><a href="module-model.Pager.html#hasPreviousPage">hasPreviousPage</a></li></ul></li><li><a href="module-system.System.html">System</a><ul class='methods'><li data-type='method'><a href="module-system.System.html#.compareVersions">compareVersions</a></li><li data-type='method'><a href="module-system.System.html#.getSystem">getSystem</a></li><li data-type='method'><a href="module-system.System.html#.isVersionCompatible">isVersionCompatible</a></li><li data-type='method'><a href="module-system.System.html#.parseVersionString">parseVersionString</a></li><li data-type='method'><a href="module-system.System.html#installAppVersion">installAppVersion</a></li><li data-type='method'><a href="module-system.System.html#loadAppStore">loadAppStore</a></li><li data-type='method'><a href="module-system.System.html#loadInstalledApps">loadInstalledApps</a></li><li data-type='method'><a href="module-system.System.html#reloadApps">reloadApps</a></li><li data-type='method'><a href="module-system.System.html#setInstalledApps">setInstalledApps</a></li><li data-type='method'><a href="module-system.System.html#setSystemInfo">setSystemInfo</a></li><li data-type='method'><a href="module-system.System.html#uninstallApp">uninstallApp</a></li><li data-type='method'><a href="module-system.System.html#uploadApp">uploadApp</a></li></ul></li><li><a href="module-system.SystemConfiguration.html">SystemConfiguration</a><ul class='methods'><li data-type='method'><a href="module-system.SystemConfiguration.html#all">all</a></li><li data-type='method'><a href="module-system.SystemConfiguration.html#get">get</a></li></ul></li><li><a href="module-system.SystemSettings.html">SystemSettings</a><ul class='methods'><li data-type='method'><a href="module-system.SystemSettings.html#all">all</a></li><li data-type='method'><a href="module-system.SystemSettings.html#get">get</a></li></ul></li></ul><h3>Modules</h3><ul><li><a href="module-analytics.html">analytics</a></li><li><a href="module-api.html">api</a></li><li><a href="module-current-user.html">current-user</a></li><li><a href="module-d2.html">d2</a><ul class='members'><li data-type='member'><a href="module-d2.html#.config">config</a></li></ul><ul class='methods'><li data-type='method'><a href="module-d2.html#.getInstance">getInstance</a></li><li data-type='method'><a href="module-d2.html#.getManifest">getManifest</a></li><li data-type='method'><a href="module-d2.html#.init">init</a></li><li data-type='method'><a href="module-d2.html#~getUserSettings">getUserSettings</a></li></ul></li><li><a href="module-datastore.html">datastore</a></li><li><a href="module-i18n.html">i18n</a></li><li><a href="module-lib_check.html">lib/check</a><ul class='methods'><li data-type='method'><a href="module-lib_check.html#.checkDefined">checkDefined</a></li><li data-type='method'><a href="module-lib_check.html#.isValidUid">isValidUid</a></li></ul></li><li><a href="module-lib_utils.html">lib/utils</a><ul class='methods'><li data-type='method'><a href="module-lib_utils.html#.customEncodeURIComponent">customEncodeURIComponent</a></li><li data-type='method'><a href="module-lib_utils.html#.pick">pick</a></li></ul></li><li><a href="module-model.html">model</a></li><li><a href="module-period_generators.html">period/generators</a><ul class='methods'><li data-type='method'><a href="module-period_generators.html#.createPeriodGeneratorsForLocale">createPeriodGeneratorsForLocale</a></li></ul></li><li><a href="module-system.html">system</a></li><li><a href="module-uid.html">uid</a><ul class='methods'><li data-type='method'><a href="module-uid.html#.generateUid">generateUid</a></li><li data-type='method'><a href="module-uid.html#.isValidUid">isValidUid</a></li></ul></li></ul><h3>Namespaces</h3><ul><li><a href="module-d2.init-d2.html">d2</a></li></ul><h3>Tutorials</h3><ul><li><a href="tutorial-FAQ.html">FAQ</a></li><li><a href="tutorial-overview.html">overview</a></li></ul><h3>Global</h3><ul><li><a href="global.html#addDataDimension">addDataDimension</a></li><li><a href="global.html#addDataFilter">addDataFilter</a></li><li><a href="global.html#addDimension">addDimension</a></li><li><a href="global.html#addFilter">addFilter</a></li><li><a href="global.html#addOrgUnitDimension">addOrgUnitDimension</a></li><li><a href="global.html#addOrgUnitFilter">addOrgUnitFilter</a></li><li><a href="global.html#addPeriodDimension">addPeriodDimension</a></li><li><a href="global.html#addPeriodFilter">addPeriodFilter</a></li><li><a href="global.html#byOrgUnit">byOrgUnit</a></li><li><a href="global.html#computeWeekBasedPeriod">computeWeekBasedPeriod</a></li><li><a href="global.html#getAll">getAll</a></li><li><a href="global.html">getGeoFeatures</a></li><li><a href="global.html">isValidDisplayName</a></li><li><a href="global.html">isValidOrgUnit</a></li><li><a href="global.html">isValidOrgUnitGroup</a></li><li><a href="global.html">isValidOrgUnitLevel</a></li><li><a href="global.html">isValidUserOrgUnit</a></li><li><a href="global.html#withAggregateData">withAggregateData</a></li><li><a href="global.html#withAggregationType">withAggregationType</a></li><li><a href="global.html#withApprovalLevel">withApprovalLevel</a></li><li><a href="global.html#withAsc">withAsc</a></li><li><a href="global.html#withBbox">withBbox</a></li><li><a href="global.html#withClusterSize">withClusterSize</a></li><li><a href="global.html#withCollapseDataDimensions">withCollapseDataDimensions</a></li><li><a href="global.html#withColumns">withColumns</a></li><li><a href="global.html#withCoordinateField">withCoordinateField</a></li><li><a href="global.html#withCoordinatesOnly">withCoordinatesOnly</a></li><li><a href="global.html#withDesc">withDesc</a></li><li><a href="global.html#withDisplayProperty">withDisplayProperty</a></li><li><a href="global.html#withEndDate">withEndDate</a></li><li><a href="global.html#withEventStatus">withEventStatus</a></li><li><a href="global.html#withFormat">withFormat</a></li><li><a href="global.html#withHideEmptyColumns">withHideEmptyColumns</a></li><li><a href="global.html#withHideEmptyRows">withHideEmptyRows</a></li><li><a href="global.html#withHierarchyMeta">withHierarchyMeta</a></li><li><a href="global.html#withIgnoreLimit">withIgnoreLimit</a></li><li><a href="global.html#withIncludeClusterPoints">withIncludeClusterPoints</a></li><li><a href="global.html#withIncludeMetadataDetails">withIncludeMetadataDetails</a></li><li><a href="global.html#withIncludeNumDen">withIncludeNumDen</a></li><li><a href="global.html#withInputIdScheme">withInputIdScheme</a></li><li><a href="global.html#withLimit">withLimit</a></li><li><a href="global.html#withMeasureCriteria">withMeasureCriteria</a></li><li><a href="global.html#withOuMode">withOuMode</a></li><li><a href="global.html#withOutputIdScheme">withOutputIdScheme</a></li><li><a href="global.html#withOutputType">withOutputType</a></li><li><a href="global.html#withPage">withPage</a></li><li><a href="global.html#withPageSize">withPageSize</a></li><li><a href="global.html#withParameters">withParameters</a></li><li><a href="global.html#withPath">withPath</a></li><li><a href="global.html#withPreAggregationMeasureCriteria">withPreAggregationMeasureCriteria</a></li><li><a href="global.html#withProgram">withProgram</a></li><li><a href="global.html#withProgramStatus">withProgramStatus</a></li><li><a href="global.html#withRelativePeriodDate">withRelativePeriodDate</a></li><li><a href="global.html#withRows">withRows</a></li><li><a href="global.html#withShowHierarchy">withShowHierarchy</a></li><li><a href="global.html#withSkipData">withSkipData</a></li><li><a href="global.html#withSkipMeta">withSkipMeta</a></li><li><a href="global.html#withSkipRounding">withSkipRounding</a></li><li><a href="global.html#withSortOrder">withSortOrder</a></li><li><a href="global.html#withStage">withStage</a></li><li><a href="global.html#withStartDate">withStartDate</a></li><li><a href="global.html#withTableLayout">withTableLayout</a></li><li><a href="global.html#withUserOrgUnit">withUserOrgUnit</a></li><li><a href="global.html#withValue">withValue</a></li></ul> </nav> <div id="main"> <h1 class="page-title">model/ModelDefinition.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>import { checkType, isObject, checkDefined, isDefined } from '../lib/check' import { addLockedProperty, curry, copyOwnProperties, updateAPIUrlWithBaseUrlVersionNumber, pick, } from '../lib/utils' import ModelDefinitions from './ModelDefinitions' import Model from './Model' import ModelCollection from './ModelCollection' import ModelCollectionProperty from './ModelCollectionProperty' import schemaTypes from '../lib/SchemaTypes' import Filters from './Filters' import { DIRTY_PROPERTY_LIST } from './ModelBase' import { getDefaultValuesForModelType } from './config' import { getOwnedPropertyJSON } from './helpers/json' function createModelPropertyDescriptor(propertiesObject, schemaProperty) { const propertyName = schemaProperty.collection ? schemaProperty.collectionName : schemaProperty.name const propertyDetails = { // Actual property descriptor properties configurable: false, enumerable: true, get() { return this.dataValues[propertyName] }, } // Store available constants for ENUM type properties if (schemaProperty.constants) { propertyDetails.constants = schemaProperty.constants } // Only add a setter for writable properties if (schemaProperty.writable) { propertyDetails.set = function dynamicPropertySetter(value) { // TODO: Objects and Arrays are considered unequal when their data is the same and therefore trigger a dirty if ( (!isObject(value) &amp;&amp; value !== this.dataValues[propertyName]) || isObject(value) ) { this.dirty = true this[DIRTY_PROPERTY_LIST].add(propertyName) this.dataValues[propertyName] = value } } } if (propertyName) { propertiesObject[propertyName] = propertyDetails } } function createPropertiesObject(schemaProperties) { const propertiesObject = {} const createModelPropertyDescriptorOn = curry( createModelPropertyDescriptor, propertiesObject ) ;(schemaProperties || []).forEach(createModelPropertyDescriptorOn) return propertiesObject } // eslint-disable-next-line complexity function createValidationSetting(validationObject, schemaProperty) { const propertyName = schemaProperty.collection ? schemaProperty.collectionName : schemaProperty.name const validationDetails = { persisted: schemaProperty.persisted, type: schemaTypes.typeLookup(schemaProperty.propertyType), required: schemaProperty.required, min: schemaProperty.min, max: schemaProperty.max, owner: schemaProperty.owner, unique: schemaProperty.unique, writable: schemaProperty.writable, ordered: Boolean(schemaProperty.ordered), embeddedObject: Boolean(schemaProperty.embeddedObject), } function getReferenceTypeFrom(property) { if (property.href) { return property.href.split('/').pop() } return undefined } // Add a referenceType to be able to get a hold of the reference objects model. if ( validationDetails.type === 'REFERENCE' || (validationDetails.type === 'COLLECTION' &amp;&amp; schemaProperty.itemPropertyType === 'REFERENCE') ) { validationDetails.referenceType = getReferenceTypeFrom(schemaProperty) } if (propertyName) { validationObject[propertyName] = validationDetails } } function createValidations(schemaProperties) { const validationsObject = {} const createModelPropertyOn = curry( createValidationSetting, validationsObject ) ;(schemaProperties || []).forEach(createModelPropertyOn) return validationsObject } function shouldBeModelCollectionProperty(model, models) { // eslint-disable-next-line complexity return function shouldBeModelCollectionPropertyIterator(modelProperty) { return ( model &amp;&amp; models &amp;&amp; model.modelDefinition &amp;&amp; model.modelDefinition.modelValidations &amp;&amp; model.modelDefinition.modelValidations[modelProperty] &amp;&amp; model.modelDefinition.modelValidations[modelProperty].type === 'COLLECTION' &amp;&amp; models.hasOwnProperty( model.modelDefinition.modelValidations[modelProperty] .referenceType ) ) } } function isAnUpdate(modelToCheck) { return Boolean(modelToCheck.id) } const translatableProperties = new WeakMap() /** * Definition of a Model. Basically this object contains the meta data related to the Model. Like `name`, `apiEndPoint`, `modelValidation`, etc. * It also has methods to create and load Models that are based on this definition. The Data element `ModelDefinition` would be used to create Data Element `Model`s * * Note: ModelDefinition has a property `api` that is used for the communication with the dhis2 api. The value of this * property is an instance of `Api`. * * @memberof module:model */ class ModelDefinition { // eslint-disable-next-line complexity constructor(schema = {}, properties, validations, attributes, authorities) { checkType(schema.singular, 'string') checkType(schema.plural, 'string', 'Plural') addLockedProperty(this, 'name', schema.singular) addLockedProperty(this, 'displayName', schema.displayName) addLockedProperty(this, 'plural', schema.plural) addLockedProperty(this, 'isShareable', schema.shareable || false) addLockedProperty(this, 'isMetaData', schema.metadata || false) addLockedProperty(this, 'apiEndpoint', schema.apiEndpoint) addLockedProperty(this, 'javaClass', schema.klass) addLockedProperty( this, 'identifiableObject', schema &amp;&amp; schema.identifiableObject ) addLockedProperty(this, 'modelProperties', properties) addLockedProperty(this, 'modelValidations', validations) addLockedProperty(this, 'attributeProperties', attributes) addLockedProperty(this, 'authorities', authorities) addLockedProperty(this, 'translatable', schema.translatable || false) this.filters = Filters.getFilters(this) translatableProperties.set( this, (schema.properties || []) .filter(prop => prop.translationKey) .map(({ name, translationKey }) => ({ name, translationKey })) ) // TODO: The function getOwnedPropertyJSON should probably not be exposed, perhaps we could have a getJSONForModel(ownedPropertiesOnly=true) method. this.getOwnedPropertyJSON = getOwnedPropertyJSON.bind(this) } filter() { return this.clone().filters } /** * Creates a fresh Model instance based on the `ModelDefinition`. If data is passed into the method that * data will be loaded into the matching properties of the model. * * @param {Object} [data] Data values that should be loaded into the model. * * @returns {Model} Returns the newly created model instance. * * @example * dataElement.create({name: 'ANC', id: 'd2sf33s3ssf'}); */ create(data) { const model = Model.create(this) const models = ModelDefinitions.getModelDefinitions() const dataValues = data ? Object.assign({}, data) : getDefaultValuesForModelType(model.modelDefinition.name) Object.keys(model) .filter(shouldBeModelCollectionProperty(model, models)) .forEach(modelProperty => { const { referenceType, } = model.modelDefinition.modelValidations[modelProperty] let values = [] if (Array.isArray(dataValues[modelProperty])) { values = dataValues[modelProperty].map(value => models[referenceType].create(value) ) } else if ( dataValues[modelProperty] === true || dataValues[modelProperty] === undefined ) { values = dataValues[modelProperty] } dataValues[modelProperty] = ModelCollectionProperty.create( model, models[referenceType], modelProperty, values ) model.dataValues[modelProperty] = dataValues[modelProperty] }) Object.keys(model) .filter( modelProperty => !shouldBeModelCollectionProperty( model, models )(modelProperty) ) .forEach(modelProperty => { model.dataValues[modelProperty] = dataValues[modelProperty] }) return model } clone() { const ModelDefinitionPrototype = Object.getPrototypeOf(this) const priorFilters = this.filters.getFilterList() const clonedDefinition = copyOwnProperties( Object.create(ModelDefinitionPrototype), this ) clonedDefinition.filters = Filters.getFilters( clonedDefinition, priorFilters ) return clonedDefinition } /** * Get a `Model` instance from the api loaded with data that relates to `identifier`. * This will do an API call and return a Promise that resolves with a `Model` or rejects with the api error message. * * @param {String} identifier * @param {Object} [queryParams={fields: ':all'}] Query parameters that should be passed to the GET query. * @returns {Promise} Resolves with a `Model` instance or an error message. * * @example * //Do a get request for the dataElement with given id (d2sf33s3ssf) and print it's name * //when that request is complete and the model is loaded. * dataElement.get('d2sf33s3ssf') * .then(model => console.log(model.name)); */ get( identifier, queryParams = { fields: ':all,attributeValues[:all,attribute[id,name,displayName]]', } ) { checkDefined(identifier, 'Identifier') if (Array.isArray(identifier)) { return this.list({ filter: [`id:in:[${identifier.join(',')}]`] }) } // TODO: should throw error if API has not been defined return this.api .get([this.apiEndpoint, identifier].join('/'), queryParams) .then(data => this.create(data)) .catch(response => { if (response.message) { return Promise.reject(response.message) } return Promise.reject(response) }) } /** * Loads a list of models. * * @param {Object} [listParams={fields: ':all'}] Query parameters that should be passed to the GET query. * @returns {Promise} ModelCollection collection of models objects of the `ModelDefinition` type. * * @example * // Loads a list of models and prints their name. * dataElement.list() * .then(modelCollection => { * modelCollection.forEach(model => console.log(model.name)); * }); */ list(listParams = {}) { const { apiEndpoint, ...extraParams } = listParams const definedRootJunction = this.filters.rootJunction ? { rootJunction: this.filters.rootJunction } : {} const params = Object.assign( { fields: ':all' }, definedRootJunction, extraParams ) const definedFilters = this.filters.getQueryFilterValues() if (!isDefined(params.filter)) { delete params.filter if (definedFilters.length) { params.filter = definedFilters } } // If listParams.apiEndpoint exists, send the request there in stead of this.apiEndpoint return this.api .get(apiEndpoint || this.apiEndpoint, params) .then(responseData => ModelCollection.create( this, responseData[this.plural].map(data => this.create(data)), Object.assign(responseData.pager || {}, { query: params }) ) ) } /** * This method is used by the `Model` instances to save the model when calling `model.save()`. * * @param {Model} model The model that should be saved to the server. * @returns {Promise} A promise which resolves when the save was successful * or rejects when it failed. The promise will resolve with the data that is * returned from the server. * * @note {warning} This should generally not be called directly. */ // TODO: check the return status of the save to see if it was actually successful and not ignored save(model) { if (isAnUpdate(model)) { const jsonPayload = getOwnedPropertyJSON.bind(this)(model) // Fallback to modelDefinition if href is unavailable const updateUrl = model.dataValues.href ? updateAPIUrlWithBaseUrlVersionNumber( model.dataValues.href, this.api.baseUrl ) : [model.modelDefinition.apiEndpoint, model.dataValues.id].join( '/' ) // Save the existing model return this.api.update(updateUrl, jsonPayload, true) } return this.saveNew(model) } saveNew(model) { const jsonPayload = getOwnedPropertyJSON.bind(this)(model) // Its a new object return this.api.post(this.apiEndpoint, jsonPayload) } /** * This method returns a list of property names that that are defined * as "owner" properties on this schema. This means these properties are used * when saving the model to the server. * * @returns {String[]} Returns an array of property names. * * @example * dataElement.getOwnedPropertyNames() */ getOwnedPropertyNames() { return Object.keys(this.modelValidations).filter( propertyName => this.modelValidations[propertyName].owner ) } /** * This method is used by the `Model` instances to delete the model when calling `model.delete()`. * * @returns {Promise} Returns a promise to the deletion operation * * @note {warning} This should generally not be called directly. */ delete(model) { if (model.dataValues.href) { return this.api.delete(model.dataValues.href) } return this.api.delete( [model.modelDefinition.apiEndpoint, model.dataValues.id].join('/') ) } /** * Check for if the Model supports translations * * @returns {Boolean} True when the schema can be translated, false otherwise */ isTranslatable() { return this.translatable } /** * These properties can be translated using the DHIS2 _database_ translations. * * @returns {String[]} Returns a list of property names on the object that are translatable. */ getTranslatableProperties() { return translatableProperties.get(this).map(pick('name')) } /** * This method is similar to getTranslatableProperties() but in addition to the property names also returns the * `translationKey` that is used to save the translations for the property names. * * @returns {Object[]} Returns an array with objects that have `name` and `translationKey` properties. */ getTranslatablePropertiesWithKeys() { return translatableProperties.get(this) } /** * @static * * This method creates a new `ModelDefinition` based on a JSON structure called * a schema. A schema represents the structure of a domain model as it is * required by DHIS. Since these schemas can not be altered on the server from * the modelDefinition is frozen to prevent accidental changes to the definition. * * @param {Object} schema A schema definition received from the web api (/api/schemas) * @param {Object[]} attributes A list of attribute objects that describe custom attributes (/api/attributes) * * @returns {ModelDefinition} Frozen model definition object. * * @example * ModelDefinition.createFromSchema(schemaDefinition, attributes); * * @note {info} An example of a schema definition can be found on * https://apps.dhis2.org/demo/api/schemas/dataElement */ static createFromSchema(schema, attributes = []) { let ModelDefinitionClass checkType(schema, Object, 'Schema') if ( typeof ModelDefinition.specialClasses[schema.singular] === 'function' ) { ModelDefinitionClass = ModelDefinition.specialClasses[schema.singular] } else { ModelDefinitionClass = ModelDefinition } return Object.freeze( new ModelDefinitionClass( schema, Object.freeze(createPropertiesObject(schema.properties)), Object.freeze(createValidations(schema.properties)), attributes.reduce((current, attributeDefinition) => { current[attributeDefinition.name] = attributeDefinition return current }, {}), schema.authorities ) ) } } class UserModelDefinition extends ModelDefinition { // TODO: userCredentials should always be included, no matter what the query params, that is currently not the case get(identifier, queryParams = { fields: ':all,userCredentials[:owner]' }) { return super.get(identifier, queryParams) } } class DataSetModelDefinition extends ModelDefinition { create(data = {}) { const hasData = Boolean(Object.keys(data).length) // Filter out the compulsoryDataElementOperands structure from the retrieved data // This structure does not follow the convention of a typical reference. We can not create a proper // ModelCollection for this collection. const dataClone = Object.keys(data) .filter(key => key !== 'compulsoryDataElementOperands') .reduce((obj, key) => { obj[key] = data[key] return obj }, {}) // Create the model using the usual way of creating a model // Only pass data when there is data in the object passed to the constructor. This will guarantee // that the empty ModelCollections are created properly. const model = super.create(hasData ? dataClone : undefined) // Set the compulsoryDataElementOperands onto the dataValues so it will be included during the save operations model.dataValues.compulsoryDataElementOperands = data.compulsoryDataElementOperands return model } } class OrganisationUnitModelDefinition extends ModelDefinition { // If a 'root' is specified when listing organisation units the results will be limited to the root and its // descendants. This is special behavior for the organisation unit API endpoint, which is documented here: // https://dhis2.github.io/dhis2-docs/master/en/developer/html/webapi_organisation_units.html list(extraParams = {}) { const { root, ...params } = extraParams if (extraParams.hasOwnProperty('root') &amp;&amp; root) { params.apiEndpoint = `${this.apiEndpoint}/${root}` } return super.list(params) } } ModelDefinition.specialClasses = { user: UserModelDefinition, dataSet: DataSetModelDefinition, organisationUnit: OrganisationUnitModelDefinition, } export default ModelDefinition </code></pre> </article> </section> </div> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.6</a> on Thu Nov 18 2021 08:51:53 GMT+0000 (Coordinated Universal Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme. </footer> <script>prettyPrint();</script> <script src="scripts/linenumber.js"></script> </body> </html>