diff --git a/.prettierrc b/.prettierrc index fe49d57..ceab1cf 100644 --- a/.prettierrc +++ b/.prettierrc @@ -3,5 +3,6 @@ "tabWidth": 2, "singleQuote": true, "arrowParens": "avoid", - "printWidth": 80 + "printWidth": 80, + "proseWrap": "always" } diff --git a/README.md b/README.md index 6f107b9..5431816 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,8 @@ Language Pack for building expressions and operations for working with the ## Documentation View the [docs site](https://openfn.github.io/language-dhis2/) for full -technical documentation. Below, find a samples of the most commonly used helper -functions. +technical documentation and **lots of examples** for how to use the various +helper functions. ## Sample State @@ -16,165 +16,21 @@ functions. "configuration": { "username": "admin", "password": "district", - "hostUrl": "https://play.dhis2.org/2.35.1" + "hostUrl": "https://play.dhis2.org/2.36.6" }, - "data": { - "a": 1, - "b": 2 - } + "data": { "a": 1, "b": 2 } } ``` -## Analytics API - -#### Fetch analytics data for PMTCT data over last 6 months. - -```js -fetchAnalytics({ - query: { - dimension: ['dx:CYI5LEmm3cG;GDVU1o5rTNF', 'pe:LAST_6_MONTHS'], - filter: 'ou:GHlyx9Pg9mn', - displayProperty: 'NAME', - outputIdScheme: 'UID', - }, -}); -``` - -## Tracked Entity API - -#### Create a new tracked entity instance and enroll them from a CommCare form submission. - -```js -createTEI({ - trackedEntityType: 'nEenWmSyUEp', - orgUnit: 'g8upMTyEZGZ', - attributes: [ - { - attribute: 'w75KJ2mc4zz', - value: dataValue('form.first_name')(state), - }, - { - attribute: 'zDhUuAYrxNC', - value: dataValue('form.last_name')(state), - }, - ], - enrollments: [ - { - orgUnit: 'g8upMTyEZGZ', - program: 'IpHINAT79UW', - enrollmentDate: '2019-04-08', - incidentDate: '2019-04-08', - }, - ], -}); -``` - -#### Upsert a tracked entity instance from a CommCare form submission. - -```js -upsertTEI( - 'w75KJ2mc4zz', // match on 'patientID', a custom external ID in dhis2 - { - trackedEntityType: 'nEenWmSyUEp', - orgUnit: 'g8upMTyEZGZ', - attributes: [ - { - attribute: 'w75KJ2mc4zz', - value: dataValue('form.first_name')(state), - }, - { - attribute: 'zDhUuAYrxNC', - value: dataValue('form.last_name')(state), - }, - ], - } -); -``` - -## Events API - -#### `Events API` expression - -```js -event( - fields( - field("program", "eBAyeGv0exc"), - field("orgUnit", "DiszpKrYNg8"), - field("eventDate", dataValue("date")), - field("status", "COMPLETED"), - field("storedBy", "admin"), - field("coordinate", { - "latitude": "59.8", - "longitude": "10.9" - }), - field("dataValues", function(state) { - return [ - dataElement("qrur9Dvnyt5", dataValue("prop_a"))(state) - dataElement("oZg33kd9taw", dataValue("prop_b"))(state) - dataElement("msodh3rEMJa", dataValue("prop_c"))(state) - ] - }) - ) -) -``` - -#### Current `fetchEvents API` expression (Optional `postUrl` for a complete fetch) - -```js -fetchEvents({ - fields: { - orgUnit: 'DiszpKrYNg8', - program: 'eBAyeGv0exc', - endDate: '2016-01-01', - }, - postUrl: 'https://www.openfn.org/inbox/123', -}); -``` - -#### Reference on how to query and read events https://docs.dhis2.org/2.22/en/developer/html/ch01s15.html#d5e1994 - -## Data Values / Data Value Sets API - -#### Current `DataValueSets API` expression - -```js -dataValueSet({ - dataSet: dataValue('set'), - orgUnit: 'DiszpKrYNg8', - period: '201402', - completeData: '2014-03-03', - dataValues: [ - dataElement('f7n9E0hX8qk', dataValue('data[0].site_school_number')), - dataElement('Ix2HsbDMLea', dataValue('age')), - dataElement('eY5ehpbEsB7', 30), - ], -}); -``` - -#### Current `fetchData API` expression (Optional `postUrl` for a complete fetch) - -```js -fetchData({ - fields: { - dataSet: 'pBOMPrpg1QX', - orgUnit: 'DiszpKrYNg8', - period: '201711', - }, - postUrl: 'https://www.openfn.org/inbox/123', -}); -``` - -#### Reference on how to read data values https://docs.dhis2.org/2.22/en/developer/html/ch01s13.html#d5e1642 - -[Docs](docs/index) - ## Development -Clone the repo, run `npm install`. +Clone the repo and run `npm install`. -Run tests using `npm run test` or `npm run test:watch` +Run tests using `npm run test` or `npm run test:watch`. (NB: that this repo also +contain integration tests which can be run with `npm run integration-test`.) -NB: There are two types of tests: unit tests and integration tests. +**_Make your changes to the files in `src/` and then use `npm run build` to +generate output files in `lib/`._** ### Unit Tests @@ -191,22 +47,56 @@ needs to be added. ### End-to-end integration tests -Integration tests allow us to test the end-to-end behavior of the helper functions -and also to test the examples we provide via inline documentation. +Integration tests allow us to test the end-to-end behavior of the helper +functions and also to test the examples we provide via inline documentation. For example with integration tests we answer the following question: > Does `create('events', eventPayload)` actually create a new event in a live > DHIS2 system? -To run integration tests, execute `npm run integration-test`. These -tests use network I/O and a public connection to a DHIS2 "play" server so their -timing and performance is unpredictable. Consider adding an increased timeout, -and modifying the orgUnit, program, etc., IDs set in `globalState`. - -Anytime a new example is added in the documentation of a helper function, a new -integration test should be done. +To run integration tests, execute `npm run integration-test`. These tests use +network I/O and a public connection to a DHIS2 "play" server so their timing and +performance is unpredictable. Consider adding an increased timeout, and +modifying the orgUnit, program, etc., IDs set in `globalState`. + +#### Troubleshooting the tests + +- Depending on your internet strength please consider changing the **global + timeout** in the `test/mocha.opts` file to avoid faillures related to network + timeouts. + +- The behavior of the tests in `test/integration.js` is very unpredictable; they + depend on the **configuration of a target DHIS2 instance**. Currently you need + to have at least one organisation unit with one program, one + trackedEntityInstance and one programStage in it. These components need to be + well configured for the integration tests to work. For example: the + trackedEntityInstance need to be enrolled to the program, which should be + created in that organisation unit and contains at least that programStage. If + the tests fail, you must adjust these attributes in the + [before hook](test/integration.js): + +```javascript +before(done => { + fixture.initialState = { + configuration: { + username: 'admin', + password: 'district', + hostUrl: 'https://play.dhis2.org/2.36.6', + }, + program: 'IpHINAT79UW', + orgUnit: 'DiszpKrYNg8', + trackedEntityInstance: 'uhubxsfLanV', + programStage: 'eaDHS084uMp', + }; + done(); +}); +``` -### Build +- Make sure the `update` and `upsert` integration tests don't affect those + initial organisation units, programs, programStage and trackedEntityInstance + required. Otherwise the create integration tests would be broken again; and + that's an endless faillure loop :( -Build the project using `npm run build`. +Anytime a new example is added in the documentation of a helper function, a new +integration test should be built. diff --git a/docs/Adaptor.js.html b/docs/Adaptor.js.html index 20213b7..6a14371 100644 --- a/docs/Adaptor.js.html +++ b/docs/Adaptor.js.html @@ -32,138 +32,95 @@

Source: Adaptor.js

value: true }); exports.execute = execute; -exports.getTEIs = getTEIs; -exports.upsertTEI = upsertTEI; -exports.createTEI = createTEI; -exports.updateTEI = updateTEI; -exports.getEvents = getEvents; -exports.createEvents = createEvents; -exports.updateEvents = updateEvents; -exports.getPrograms = getPrograms; -exports.createPrograms = createPrograms; -exports.updatePrograms = updatePrograms; -exports.getEnrollments = getEnrollments; -exports.enrollTEI = enrollTEI; -exports.updateEnrollments = updateEnrollments; -exports.cancelEnrollment = cancelEnrollment; -exports.completeEnrollment = completeEnrollment; -exports.getRelationships = getRelationships; -exports.getDataValues = getDataValues; -exports.createDataValues = createDataValues; -exports.generateDhis2UID = generateDhis2UID; -exports.discover = discover; -exports.getAnalytics = getAnalytics; -exports.getResources = getResources; -exports.getSchema = getSchema; -exports.getData = getData; -exports.getMetadata = getMetadata; exports.create = create; exports.update = update; +exports.get = get; +exports.discover = discover; exports.patch = patch; -exports.del = del; -exports.upsert = upsert; +exports.destroy = destroy; +exports.findAttributeValue = findAttributeValue; +exports.attr = attr; +exports.dv = dv; Object.defineProperty(exports, "field", { enumerable: true, - get: function get() { + get: function () { return _languageCommon.field; } }); Object.defineProperty(exports, "fields", { enumerable: true, - get: function get() { + get: function () { return _languageCommon.fields; } }); Object.defineProperty(exports, "sourceValue", { enumerable: true, - get: function get() { + get: function () { return _languageCommon.sourceValue; } }); Object.defineProperty(exports, "merge", { enumerable: true, - get: function get() { + get: function () { return _languageCommon.merge; } }); Object.defineProperty(exports, "each", { enumerable: true, - get: function get() { + get: function () { return _languageCommon.each; } }); Object.defineProperty(exports, "dataPath", { enumerable: true, - get: function get() { + get: function () { return _languageCommon.dataPath; } }); Object.defineProperty(exports, "dataValue", { enumerable: true, - get: function get() { + get: function () { return _languageCommon.dataValue; } }); Object.defineProperty(exports, "lastReferenceValue", { enumerable: true, - get: function get() { + get: function () { return _languageCommon.lastReferenceValue; } }); Object.defineProperty(exports, "alterState", { enumerable: true, - get: function get() { + get: function () { return _languageCommon.alterState; } }); -Object.defineProperty(exports, "http", { +Object.defineProperty(exports, "fn", { enumerable: true, - get: function get() { - return _languageCommon.http; + get: function () { + return _languageCommon.fn; } }); -Object.defineProperty(exports, "attribute", { +Object.defineProperty(exports, "http", { enumerable: true, - get: function get() { - return _Utils.attribute; + get: function () { + return _languageCommon.http; } }); var _axios = _interopRequireDefault(require("axios")); -var _languageCommon = require("@openfn/language-common"); - var _lodash = require("lodash"); -var _Utils = require("./Utils"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } - -function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } - -function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); } - -function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } - -function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } - -function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } - -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } - -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } - -function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } +var _languageCommon = require("@openfn/language-common"); -function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } +var _Utils = require("./Utils"); -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } +var _Client = require("./Client"); -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } +/** @module Adaptor */ /** * Execute a sequence of operations. @@ -177,17 +134,15 @@

Source: Adaptor.js

* @param {Operations} operations - Operations to be performed. * @returns {Operation} */ -function execute() { - for (var _len = arguments.length, operations = new Array(_len), _key = 0; _key < _len; _key++) { - operations[_key] = arguments[_key]; - } - - var initialState = { +function execute(...operations) { + const initialState = { references: [], data: null }; - return function (state) { - return _languageCommon.execute.apply(void 0, [configMigrationHelper].concat(operations))(_objectSpread({}, initialState, {}, state)); + return state => { + return (0, _languageCommon.execute)(configMigrationHelper, ...operations)({ ...initialState, + ...state + }); }; } /** @@ -202,9 +157,10 @@

Source: Adaptor.js

function configMigrationHelper(state) { - var _state$configuration = state.configuration, - hostUrl = _state$configuration.hostUrl, - apiUrl = _state$configuration.apiUrl; + const { + hostUrl, + apiUrl + } = state.configuration; if (!hostUrl) { _Utils.Log.warn('DEPRECATION WARNING: Please migrate instance address from `apiUrl` to `hostUrl`.'); @@ -214,19 +170,21 @@

Source: Adaptor.js

} return state; -} +} // NOTE: In order to prevent unintended exposure of authentication information +// in the logs, we make use of an axios interceptor. + -_axios["default"].interceptors.response.use(function (response) { +_axios.default.interceptors.response.use(function (response) { var _response$headers$con, _response; - var contentType = (_response$headers$con = response.headers['content-type']) === null || _response$headers$con === void 0 ? void 0 : _response$headers$con.split(';')[0]; - var acceptHeaders = response.config.headers['Accept'].split(';')[0].split(','); + const contentType = (_response$headers$con = response.headers['content-type']) === null || _response$headers$con === void 0 ? void 0 : _response$headers$con.split(';')[0]; + const acceptHeaders = response.config.headers['Accept'].split(';')[0].split(','); if (response.config.method === 'get') { if ((0, _lodash.indexOf)(acceptHeaders, contentType) === -1) { - var newError = { + const newError = { status: 404, - message: 'Unexpected content,returned', + message: 'Unexpected content returned', responseData: response.data }; @@ -238,727 +196,264 @@

Source: Adaptor.js

if (typeof ((_response = response) === null || _response === void 0 ? void 0 : _response.data) === 'string' && contentType === (_Utils.CONTENT_TYPES === null || _Utils.CONTENT_TYPES === void 0 ? void 0 : _Utils.CONTENT_TYPES.json)) { try { - response = _objectSpread({}, response, { + response = { ...response, data: JSON.parse(response.data) - }); + }; } catch (error) { - /* Keep quiet */ + _Utils.Log.warn('Non-JSON response detected, unable to parse.'); } } return response; }, function (error) { - var _error$response3, _error$response3$data; - - _Utils.Log.error("".concat(error === null || error === void 0 ? void 0 : error.message)); + var _error$config, _error$config2, _error$response, _error$response$data, _error$response2; - try { - var _error$response, _error$response$data; + if ((_error$config = error.config) === null || _error$config === void 0 ? void 0 : _error$config.auth) error.config.auth = '--REDACTED--'; + if ((_error$config2 = error.config) === null || _error$config2 === void 0 ? void 0 : _error$config2.data) error.config.data = '--REDACTED--'; + const details = (_error$response = error.response) === null || _error$response === void 0 ? void 0 : (_error$response$data = _error$response.data) === null || _error$response$data === void 0 ? void 0 : _error$response$data.response; - console.log(JSON.stringify((_error$response = error.response) === null || _error$response === void 0 ? void 0 : (_error$response$data = _error$response.data) === null || _error$response$data === void 0 ? void 0 : _error$response$data.response, null, 2)); - } catch (err) { - var _error$response2, _error$response2$data; + _Utils.Log.error(error.message || "That didn't work."); - /* Keep quiet! Just log the above error again */ - console.log((_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : (_error$response2$data = _error$response2.data) === null || _error$response2$data === void 0 ? void 0 : _error$response2$data.response); - } - - console.log((_error$response3 = error.response) === null || _error$response3 === void 0 ? void 0 : (_error$response3$data = _error$response3.data) === null || _error$response3$data === void 0 ? void 0 : _error$response3$data.response); - return Promise.reject(error); + if (details) console.log(JSON.stringify(details, null, 2)); + return Promise.reject({ + request: error.config, + error: error.message, + response: (_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.data + }); }); /** - * Get Tracked Entity Instance(s). + * Create a record * @public * @function - * @param {Object} [params] - Optional `query parameters` e.g. `{ou: 'DiszpKrYNg8', filters: ['lZGmxYbs97q':GT:5']}`. Run `discover` or see {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html DHIS2 docs} for more details on which params to use when querying tracked entities instances. - * @param {{apiVersion: number,responseType: string}} [options] - `Optional` options for `getTEIs` operation. Defaults to `{apiVersion: state.configuration.apiVersion, responseType: 'json'}`. - * @param {function} [callback] - Optional callback to handle the response. + * @param {string} resourceType - Type of resource to create. E.g. `trackedEntityInstances`, `programs`, `events`, ... + * @param {Object} data - Data that will be used to create a given instance of resource. To create a single instance of a resource, `data` must be a javascript object, and to create multiple instances of a resources, `data` must be an array of javascript objects. + * @param {Object} [options] - Optional `options` to define URL parameters via params (E.g. `filter`, `dimension` and other import parameters), request config (E.g. `auth`) and the DHIS2 apiVersion. + * @param {function} [callback] - Optional callback to handle the response * @returns {Operation} - * @example <caption>- Example `getTEIs` `expression.js` for fetching a `single` `Tracked Entity Instance` with all the fields included.</caption> - * getTEIs({ - * fields: '*', - * ou: 'CMqUILyVnBL', - * trackedEntityInstance: 'HNTA9qD6EEG', - * skipPaging: true, + * @example <caption>a program</caption> + * create('programs', { + * name: 'name 20', + * shortName: 'n20', + * programType: 'WITHOUT_REGISTRATION', * }); - */ - - -function getTEIs(params, options, callback) { - return function (state) { - options = (0, _languageCommon.expandReferences)(options)(state); - if (options) options.operationName = 'getTEIs';else { - options = { - operationName: 'getTEIs' - }; - } - return getData('trackedEntityInstances', params, options, callback)(state); - }; -} -/** - * Update TEI if exists otherwise create. - * - Update if the record exists otherwise insert a new record. - * - This is useful for idempotency and duplicate record management. - * @public - * @function - * @param {string} uniqueAttributeId - Tracked Entity Instance unique identifier attribute used during matching. - * @param {Object} data - Payload data for new tracked entity instance or updated data for an existing tracked entity instance. - * @param {{apiVersion: number,strict: boolean,responseType: string}} [options] - `Optional` options for `upsertTEI` operation. Defaults to `{apiVersion: state.configuration.apiVersion,strict: true,responseType: 'json'}`. - * @param {function} [callback] - Optional `callback` to handle the response. - * @throws {RangeError} - Throws `RangeError` when `uniqueAttributeId` is `invalid` or `not unique`. - * @returns {Operation} - * @example <caption>- Example `expression.js` for upserting a tracked entity instance on attribute with Id `lZGmxYbs97q`.</caption> - * upsertTEI('lZGmxYbs97q', { + * @example <caption>an event</caption> + * create('events', { + * program: 'eBAyeGv0exc', + * orgUnit: 'DiszpKrYNg8', + * status: 'COMPLETED', + * }); + * @example <caption>a trackedEntityInstance</caption> + * create('trackedEntityInstances', { * orgUnit: 'TSyzvBiovKh', * trackedEntityType: 'nEenWmSyUEp', * attributes: [ * { - * attribute: 'lZGmxYbs97q', - * value: '77790012', - * }, - * { * attribute: 'w75KJ2mc4zz', * value: 'Gigiwe', * }, + * ] + * }); + * @example <caption>a dataSet</caption> + * create('dataSets', { name: 'OpenFn Data Set', periodType: 'Monthly' }); + * @example <caption>a dataSetNotification</caption> + * create('dataSetNotificationTemplates', { + * dataSetNotificationTrigger: 'DATA_SET_COMPLETION', + * notificationRecipient: 'ORGANISATION_UNIT_CONTACT', + * name: 'Notification', + * messageTemplate: 'Hello', + * deliveryChannels: ['SMS'], + * dataSets: [], + * }); + * @example <caption>a dataElement</caption> + * create('dataElements', { + * aggregationType: 'SUM', + * domainType: 'AGGREGATE', + * valueType: 'NUMBER', + * name: 'Paracetamol', + * shortName: 'Para', + * }); + * @example <caption>a dataElementGroup</caption> + * create('dataElementGroups', { + * name: 'Data Element Group 1', + * dataElements: [], + * }); + * @example <caption>a dataElementGroupSet</caption> + * create('dataElementGroupSets', { + * name: 'Data Element Group Set 4', + * dataDimension: true, + * shortName: 'DEGS4', + * dataElementGroups: [], + * }); + * @example <caption>a dataValueSet</caption> + * create('dataValueSets', { + * dataElement: 'f7n9E0hX8qk', + * period: '201401', + * orgUnit: 'DiszpKrYNg8', + * value: '12', + * }); + * @example <caption>a dataValueSet with related dataValues</caption> + * create('dataValueSets', { + * dataSet: 'pBOMPrpg1QX', + * completeDate: '2014-02-03', + * period: '201401', + * orgUnit: 'DiszpKrYNg8', + * dataValues: [ * { - * attribute: 'zDhUuAYrxNC', - * value: 'Mwanza', + * dataElement: 'f7n9E0hX8qk', + * value: '1', + * }, + * { + * dataElement: 'Ix2HsbDMLea', + * value: '2', + * }, + * { + * dataElement: 'eY5ehpbEsB7', + * value: '3', * }, * ], * }); - */ - - -function upsertTEI(uniqueAttributeId, data, options, callback) { - return function (state) { - var _options$apiVersion, _options, _options$strict, _options2, _body$attributes, _body$attributes$find; - - uniqueAttributeId = (0, _languageCommon.expandReferences)(uniqueAttributeId)(state); - var body = (0, _languageCommon.expandReferences)(data)(state); - options = (0, _languageCommon.expandReferences)(options)(state); - if (options) options.operationName = 'upsertTEI';else { - options = { - operationName: 'upsertTEI' - }; - } - var _state$configuration2 = state.configuration, - password = _state$configuration2.password, - username = _state$configuration2.username, - hostUrl = _state$configuration2.hostUrl; - var apiVersion = (_options$apiVersion = (_options = options) === null || _options === void 0 ? void 0 : _options.apiVersion) !== null && _options$apiVersion !== void 0 ? _options$apiVersion : state.configuration.apiVersion; - var strict = (_options$strict = (_options2 = options) === null || _options2 === void 0 ? void 0 : _options2.strict) !== null && _options$strict !== void 0 ? _options$strict : true; - var params = { - ou: body.orgUnit - }; - var uniqueAttributeValue = (_body$attributes = body.attributes) === null || _body$attributes === void 0 ? void 0 : (_body$attributes$find = _body$attributes.find(function (obj) { - return (obj === null || obj === void 0 ? void 0 : obj.attribute) === uniqueAttributeId; - })) === null || _body$attributes$find === void 0 ? void 0 : _body$attributes$find.value; - var trackedEntityType = body.trackedEntityType; - var uniqueAttributeUrl = (0, _Utils.buildUrl)("/trackedEntityAttributes/".concat(uniqueAttributeId), hostUrl, apiVersion); - var trackedEntityTypeUrl = (0, _Utils.buildUrl)("/trackedEntityTypes/".concat(trackedEntityType, "?fields=*"), hostUrl, apiVersion); - - var findTrackedEntityType = function findTrackedEntityType() { - return _axios["default"].get(trackedEntityTypeUrl, { - auth: { - username: username, - password: password - } - }).then(function (result) { - var _result$data, _result$data$trackedE; - - var attribute = (_result$data = result.data) === null || _result$data === void 0 ? void 0 : (_result$data$trackedE = _result$data.trackedEntityTypeAttributes) === null || _result$data$trackedE === void 0 ? void 0 : _result$data$trackedE.find(function (obj) { - var _obj$trackedEntityAtt; - - return (obj === null || obj === void 0 ? void 0 : (_obj$trackedEntityAtt = obj.trackedEntityAttribute) === null || _obj$trackedEntityAtt === void 0 ? void 0 : _obj$trackedEntityAtt.id) === uniqueAttributeId; - }); - return _objectSpread({}, result.data, { - upsertAttributeAssigned: attribute ? true : false - }); - }); - }; - - var isAttributeUnique = function isAttributeUnique() { - return _axios["default"].get(uniqueAttributeUrl, { - auth: { - username: username, - password: password - } - }).then(function (result) { - var foundAttribute = result.data; - return { - unique: foundAttribute.unique, - name: foundAttribute.name - }; - }); - }; - - return Promise.all([findTrackedEntityType(), strict === true ? isAttributeUnique() : Promise.resolve({ - unique: true - })]).then(function (_ref) { - var _ref2 = _slicedToArray(_ref, 2), - entityType = _ref2[0], - attribute = _ref2[1]; - - if (!entityType.upsertAttributeAssigned) { - _Utils.Log.error(''); - - throw new RangeError("Tracked Entity Attribute ".concat(uniqueAttributeId, " is not assigned to the ").concat(entityType.name, " Entity Type.")); - } - - if (!attribute.unique) { - var _attribute$name; - - _Utils.Log.error(''); - - throw new RangeError("Attribute ".concat((_attribute$name = attribute.name) !== null && _attribute$name !== void 0 ? _attribute$name : '', "(").concat(uniqueAttributeId, ") is not marked as unique.")); - } - - return upsert('trackedEntityInstances', { - attributeId: uniqueAttributeId, - attributeValue: uniqueAttributeValue - }, body, params, options, callback)(state); - }); - }; -} -/** - * Create Tracked Entity Instance. - * @public - * @function - * @param {Object} data - The update data containing new values. - * @param {Object} [params] - Optional `import parameters` for a given a resource. E.g. `{dryRun: true, importStrategy: CREATE}` See {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html#import-parameters_1 DHIS2 Import parameters documentation} or run `discover`. Defauls to `DHIS2 default import parameters`. - * @param {{apiVersion: number,responseType: string}} [options] - `Optional` options for `createTEI` operation. Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}`. - * @param {function} [callback] - Optional callback to handle the response. - * @returns {Operation} - * @example <caption>- Example `expression.js` of `createTEI`.</caption> - * createTEI({ - * orgUnit: 'TSyzvBiovKh', - * trackedEntityType: 'nEenWmSyUEp', - * attributes: [ - * { - * attribute: 'lZGmxYbs97q', - * value: valUpsertTEI, - * }, - * { - * attribute: 'w75KJ2mc4zz', - * value: 'Gigiwe', - * }, - * ], - * enrollments: [ - * { - * orgUnit: 'TSyzvBiovKh', - * program: 'fDd25txQckK', - * programState: 'lST1OZ5BDJ2', - * enrollmentDate: '2021-01-04', - * incidentDate: '2021-01-04', - * }, - * ], + * @example <caption>an enrollment</caption> + * create('enrollments', { + * trackedEntityInstance: 'bmshzEacgxa', + * orgUnit: 'TSyzvBiovKh', + * program: 'gZBxv9Ujxg0', + * enrollmentDate: '2013-09-17', + * incidentDate: '2013-09-17', * }); */ -function createTEI(data, params, options, callback) { - return function (state) { +function create(resourceType, data, options = {}, callback = false) { + return state => { + console.log(`Preparing create operation...`); + resourceType = (0, _languageCommon.expandReferences)(resourceType)(state); + data = (0, _languageCommon.expandReferences)(data)(state); options = (0, _languageCommon.expandReferences)(options)(state); - if (options) options.operationName = 'createTEI';else { - options = { - operationName: 'createTEI' - }; - } - return create('trackedEntityInstances', data, params, options, callback)(state); + const { + params, + requestConfig + } = options; + const { + configuration + } = state; + return (0, _Client.request)(configuration, { + method: 'post', + url: (0, _Utils.generateUrl)(configuration, options, resourceType), + params, + data: (0, _Utils.nestArray)(data, resourceType), + ...requestConfig + }).then(result => { + _Utils.Log.success(`Created ${resourceType}: ${result.headers.location}`); + + return (0, _Utils.handleResponse)(result, state, callback); + }); }; } /** - * Update a Tracked Entity Instance. + * Update data. A generic helper function to update a resource object of any type. + * Updating an object requires to send `all required fields` or the `full body` * @public * @function - * @param {string} path - Path to the object being updated. This can be an `id` or path to an `object` in a `nested collection` on the object(E.g. `/api/{collection-object}/{collection-object-id}/{collection-name}/{object-id}`). - * @param {Object} data - The update data containing new values. - * @param {Object} [params] - Optional `import parameters` for a given a resource. E.g. `{dryRun: true, importStrategy: CREATE, filters:[]}` See {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html#import-parameters_1 DHIS2 Import parameters documentation} or run `discover`. Defauls to `DHIS2 default import parameters`. - * @param {{apiVersion: number,responseType: string}} [options] - `Optional` options for `updateTEI` operation. Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}`. - * @param {function} [callback] - Optional callback to handle the response. + * @param {string} resourceType - The type of resource to be updated. E.g. `dataElements`, `organisationUnits`, etc. + * @param {string} path - The `id` or `path` to the `object` to be updated. E.g. `FTRrcoaog83` or `FTRrcoaog83/{collection-name}/{object-id}` + * @param {Object} data - Data to update. It requires to send `all required fields` or the `full body`. If you want `partial updates`, use `patch` operation. + * @param {Object} [options] - Optional `options` to define URL parameters via params (E.g. `filter`, `dimension` and other import parameters), request config (E.g. `auth`) and the DHIS2 apiVersion. + * @param {function} [callback] - Optional callback to handle the response * @returns {Operation} - * @example <caption>- Example `expression.js` of `updateTEI`.</caption> - * updateTEI('PVqUD2hvU4E', { - * orgUnit: 'TSyzvBiovKh', - * trackedEntityType: 'nEenWmSyUEp', - * attributes: [ - * { - * attribute: 'lZGmxYbs97q', - * value: valUpsertTEI, - * }, - * { - * attribute: 'w75KJ2mc4zz', - * value: 'Gigiwe', - * }, - * ], - * enrollments: [ - * { - * orgUnit: 'TSyzvBiovKh', - * program: 'fDd25txQckK', - * programState: 'lST1OZ5BDJ2', - * enrollmentDate: '2021-01-04', - * incidentDate: '2021-01-04', - * }, - * ], + * @example <caption>a program</caption> + * update('programs', 'qAZJCrNJK8H', { + * name: '14e1aa02c3f0a31618e096f2c6d03bed', + * shortName: '14e1aa02', + * programType: 'WITHOUT_REGISTRATION', * }); - */ - - -function updateTEI(path, data, params, options, callback) { - return function (state) { - options = (0, _languageCommon.expandReferences)(options)(state); - if (options) options.operationName = 'updateTEI';else { - options = { - operationName: 'updateTEI' - }; - } - return update('trackedEntityInstances', path, data, params, options, callback)(state); - }; -} -/** - * Get annonymous events or tracker events. - * @public - * @function - * @param {Object} params - `import` parameters for `getEvents`. See examples here - * @param {{apiVersion: number,responseType: string}} [options] - `Optional` options for `getEvents` operation. Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}`. - * @param {function} [callback] - Optional callback to handle the response. - * @returns {Operation} - * @example <caption>- Query for `all events` with `children` of a certain `organisation unit`</caption> - * getEvents({ orgUnit: 'YuQRtpLP10I', ouMode: 'CHILDREN' }); - */ - - -function getEvents(params, options, callback) { - return function (state) { - options = (0, _languageCommon.expandReferences)(options)(state); - if (options) options.operationName = 'getEvents';else { - options = { - operationName: 'getEvents' - }; - } - return getData('events', params, responseType, options, callback)(state); - }; -} -/** - * Create DHIS2 Events - * - You will need a `program` which can be looked up using the `getPrograms` operation, an `orgUnit` which can be looked up using the `getMetadata` operation and passing `{organisationUnits: true}` as `resources` param, and a list of `valid data element identifiers` which can be looked up using the `getMetadata` passing `{dataElements: true}` as `resources` param. - * - For events with registration, a `tracked entity instance identifier is required` - * - For sending `events` to `programs with multiple stages`, you will need to also include the `programStage` identifier, the identifiers for `programStages` can be found in the `programStages` resource via a call to `getMetadata` operation. - * @public - * @function - * @param {Object} data - The payload containing new values - * @param {Object} [params] - Optional `import parameters` for events. E.g. `{dryRun: true, importStrategy: CREATE, filters:[]}` See {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html#events DHIS2 Event Import parameters documentation} or run `discover`. Defauls to `DHIS2 default import parameters`. - * @param {{apiVersion: number,responseType: string}} [options] - Optional `flags` for the behavior of the `createEvents` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}` - * @param {function} [callback] - Optional callback to handle the response - * @returns {Operation} state - * @example <caption>- Example `expression.js` of `createEvents` for a `single event` can look like this:</caption> - * createEvents({ + * @example <caption>an event</caption> + * update('events', 'PVqUD2hvU4E', { * program: 'eBAyeGv0exc', - * orgUnit: 'DiszpKrYNg8', - * eventDate: date, + * orgUnit: 'Ngelehun CHC', * status: 'COMPLETED', - * completedDate: date, * storedBy: 'admin', - * coordinate: { - * latitude: 59.8, - * longitude: 10.9, - * }, - * dataValues: [ + * dataValues: [], + * }); + * @example <caption>a trackedEntityInstance</caption> + * update('trackedEntityInstances', 'IeQfgUtGPq2', { + * created: '2015-08-06T21:12:37.256', + * orgUnit: 'TSyzvBiovKh', + * createdAtClient: '2015-08-06T21:12:37.256', + * trackedEntityInstance: 'IeQfgUtGPq2', + * lastUpdated: '2015-08-06T21:12:37.257', + * trackedEntityType: 'nEenWmSyUEp', + * inactive: false, + * deleted: false, + * featureType: 'NONE', + * programOwners: [ * { - * dataElement: 'qrur9Dvnyt5', - * value: '33', + * ownerOrgUnit: 'TSyzvBiovKh', + * program: 'IpHINAT79UW', + * trackedEntityInstance: 'IeQfgUtGPq2', * }, + * ], + * enrollments: [], + * relationships: [], + * attributes: [ * { - * dataElement: 'oZg33kd9taw', - * value: 'Male', + * lastUpdated: '2016-01-12T00:00:00.000', + * displayName: 'Last name', + * created: '2016-01-12T00:00:00.000', + * valueType: 'TEXT', + * attribute: 'zDhUuAYrxNC', + * value: 'Russell', * }, * { - * dataElement: 'msodh3rEMJa', - * value: date, + * lastUpdated: '2016-01-12T00:00:00.000', + * code: 'MMD_PER_NAM', + * displayName: 'First name', + * created: '2016-01-12T00:00:00.000', + * valueType: 'TEXT', + * attribute: 'w75KJ2mc4zz', + * value: 'Catherine', * }, * ], * }); - */ - - -function createEvents(data, params, options, callback) { - return function (state) { - options = (0, _languageCommon.expandReferences)(options)(state); - if (options) options.operationName = 'createEvents';else { - options = { - operationName: 'createEvents' - }; - } - return create('events', data, params, options, callback)(state); - }; -} -/** - * Update DHIS2 Event. - * - To update an existing event, the format of the payload is the same as that of `creating an event` via `createEvents` operations - * - But you should supply the `identifier` of the object you are updating - * - The payload has to contain `all`, even `non-modified`, `attributes`. - * - Attributes that were present before and are not present in the current payload any more will be removed by DHIS2. - * - If you do not want this behavior, please use `upsert` operation to upsert your events. - * @public - * @function - * @param {string} path - Path to the object being updated. This can be an `id` or path to an `object` in a `nested collection` on the object(E.g. `/api/{collection-object}/{collection-object-id}/{collection-name}/{object-id}`) - * @param {Object} data - The update data containing new values - * @param {Object} [params] - Optional `import` parameters for `updateEvents`. E.g. `{dryRun: true, IdScheme: 'CODE'}. Defaults to DHIS2 `default params` - * @param {{apiVersion: number,responseType: string}} [options] - Optional `flags` for the behavior of the `updateEvents` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}` - * @param {function} [callback] - Optional callback to handle the response - * @returns {Operation} - * @example <caption>- Example `expression.js` of `updateEvents`</caption> - * updateEvents('PVqUD2hvU4E', { events: [ - * { - * program: 'eBAyeGv0exc', - * orgUnit: 'DiszpKrYNg8', - * eventDate: date, - * status: 'COMPLETED', - * storedBy: 'admin', - * coordinate: { - * latitude: '59.8', - * longitude: '10.9', - * }, - * dataValues: [ - * { - * dataElement: 'qrur9Dvnyt5', - * value: '22', - * }, - * { - * dataElement: 'oZg33kd9taw', - * value: 'Male', - * }, - * ], - * }] + * @example <caption>a dataSet</caption> + * update('dataSets', 'lyLU2wR22tC', { name: 'OpenFN Data Set', periodType: 'Weekly' }); + * @example <caption>a dataSetNotification</caption> + * update('dataSetNotificationTemplates', 'VbQBwdm1wVP', { + * dataSetNotificationTrigger: 'DATA_SET_COMPLETION', + * notificationRecipient: 'ORGANISATION_UNIT_CONTACT', + * name: 'Notification', + * messageTemplate: 'Hello Updated, + * deliveryChannels: ['SMS'], + * dataSets: [], * }); - */ - - -function updateEvents(path, data, params, options, callback) { - return function (state) { - options = (0, _languageCommon.expandReferences)(options)(state); - if (options) options.operationName = 'updateEvents';else { - options = { - operationName: 'updateEvents' - }; - } - return update('events', path, data, params, options, callback)(state); - }; -} -/** - * Get DHIS2 Tracker Programs. - * @public - * @function - * @param {Object} params - `import` parameters for `getPrograms`. See {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html#tracker-web-api DHIS2 api documentation for allowed query parameters } - * @param {{apiVersion: number,responseType: string}} [options] - Optional `flags` for the behavior of the `getPrograms` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}` - * @param {function} [callback] - Optional callback to handle the response - * @returns {Operation} - * @example <caption>- Query for `all programs` with a certain `organisation unit`</caption> - * getPrograms({ orgUnit: 'DiszpKrYNg8' , fields: '*' }); - */ - - -function getPrograms(params, options, callback) { - return function (state) { - options = (0, _languageCommon.expandReferences)(options)(state); - if (options) options.operationName = 'getPrograms';else { - options = { - operationName: 'getPrograms' - }; - } - return getData('programs', params, options, callback)(state); - }; -} -/** - * Create a DHIS2 Tracker Program - * @public - * @function - * @param {Object} data - The update data containing new values - * @param {Object} [params] - Optional `import` parameters for `createPrograms`. E.g. `{dryRun: true, IdScheme: 'CODE'}. Defaults to DHIS2 `default params` - * @param {{apiVersion: number,responseType: string}} [options] - Optional `flags` for the behavior of the `getPrograms` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}` - * @param {function} [callback] - Optional callback to handle the response - * @returns {Operation} - * @example <caption>- Example `expression.js` of `createPrograms` for a `single program` can look like this:</caption> - * createPrograms(state.data); - */ - - -function createPrograms(data, params, options, callback) { - return function (state) { - options = (0, _languageCommon.expandReferences)(options)(state); - if (options) options.operationName = 'createPrograms';else { - options = { - operationName: 'createPrograms' - }; - } - return create('programs', data, options, params, callback)(state); - }; -} -/** - * Update DHIS2 Tracker Programs - * - To update an existing program, the format of the payload is the same as that of `creating an event` via `createEvents` operations - * - But you should supply the `identifier` of the object you are updating - * - The payload has to contain `all`, even `non-modified`, `attributes`. - * - Attributes that were present before and are not present in the current payload any more will be removed by DHIS2. - * - If you do not want this behavior, please use `upsert` operation to upsert your events. - * @public - * @function - * @param {string} path - Path to the object being updated. This can be an `id` or path to an `object` in a `nested collection` on the object(E.g. `/api/{collection-object}/{collection-object-id}/{collection-name}/{object-id}`) - * @param {Object} data - The update data containing new values - * @param {Object} [params] - Optional `import` parameters for `updatePrograms`. E.g. `{dryRun: true, IdScheme: 'CODE'}. Defaults to DHIS2 `default params` - * @param {{apiVersion: number,responseType: string}} [options] - Optional `flags` for the behavior of the `getPrograms` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}` - * @param {function} [callback] - Optional callback to handle the response - * @returns {Operation} - * @example <caption>- Example `expression.js` of `updatePrograms`</caption> - * updatePrograms('PVqUD2hvU4E', state.data); - */ - - -function updatePrograms(path, data, params, options, callback) { - return function (state) { - options = (0, _languageCommon.expandReferences)(options)(state); - if (options) options.operationName = 'updatePrograms';else { - options = { - operationName: 'updatePrograms' - }; - } - return update('programs', path, data, params, options, callback)(state); - }; -} -/** - * Get DHIS2 Enrollments - * @public - * @function - * @param {Object} params - `Query` parameters for `getEnrollments`. See {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html#enrollment-management here} - * @param {{apiVersion: number,responseType: string}} [options] - Optional `flags` for the behavior of the `getEnrollments` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}` - * @param {function} [callback] - Optional callback to handle the response - * @returns {Operation} - * @example <caption>- To constrain the response to `enrollments` which are part of a `specific program` you can include a `program query parameter`</caption> - * getEnrollments({ - * ou: 'O6uvpzGd5pu', - * ouMode: 'DESCENDANTS', - * program: 'ur1Edk5Oe2n', - * fields: '*', + * @example <caption>a dataElement</caption> + * update('dataElements', 'FTRrcoaog83', { + * aggregationType: 'SUM', + * domainType: 'AGGREGATE', + * valueType: 'NUMBER', + * name: 'Paracetamol', + * shortName: 'Para', * }); - */ - - -function getEnrollments(params, options, callback) { - return function (state) { - options = (0, _languageCommon.expandReferences)(options)(state); - if (options) options.operationName = 'getEnrollments';else { - options = { - operationName: 'getEnrollments' - }; - } - return getData('enrollments', params, options, callback)(state); - }; -} -/** - * Enroll a TEI into a program - * - Enrolling a tracked entity instance into a program - * - For enrolling `persons` into a `program`, you will need to first get the `identifier of the person` from the `trackedEntityInstances resource` via the `getTEIs` operation. - * - Then, you will need to get the `program identifier` from the `programs` resource via the `getPrograms` operation. - * @public - * @function - * @param {Object} data - The enrollment data. See example {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html#enrollment-management here } - * @param {Object} [params] - Optional `import` parameters for `createEnrollment`. E.g. `{dryRun: true, IdScheme: 'CODE'}. Defaults to DHIS2 `default params` - * @param {{apiVersion: number,responseType: string}} [options] - Optional `flags` for the behavior of the `enrollTEI` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}` - * @param {function} [callback] - Optional callback to handle the response - * @returns {Operation} - * @example <caption>- Example `expression.js` of `createEnrollment` of a `person` into a `program` can look like this:</caption> - * enrollTEI({ - * trackedEntity: 'tracked-entity-id', - * orgUnit: 'org-unit-id', - * attributes: [ - * { - * attribute: 'attribute-id', - * value: 'attribute-value', - * }, - * ], - * enrollments: [ - * { - * orgUnit: 'org-unit-id', - * program: 'program-id', - * enrollmentDate: '2013-09-17', - * incidentDate: '2013-09-17', - * }, - * ], - *}); - */ - - -function enrollTEI(data, params, options, callback) { - return function (state) { - options = (0, _languageCommon.expandReferences)(options)(state); - if (options) options.operationName = 'enrollTEI';else { - options = { - operationName: 'enrollTEI' - }; - } - return create('enrollments', data, options, params, callback)(state); - }; -} -/** - * Update a DHIS2 Enrollemts - * - To update an existing enrollment, the format of the payload is the same as that of `creating an event` via `createEvents` operations - * - But you should supply the `identifier` of the object you are updating - * - The payload has to contain `all`, even `non-modified`, `attributes`. - * - Attributes that were present before and are not present in the current payload any more will be removed by DHIS2. - * - If you do not want this behavior, please use `upsert` operation to upsert your events. - * @public - * @function - * @param {string} path - Path to the object being updated. This can be an `id` or path to an `object` in a `nested collection` on the object(E.g. `/api/{collection-object}/{collection-object-id}/{collection-name}/{object-id}`) - * @param {Object} data - The update data containing new values - * @param {Object} [params] - Optional `import` parameters for `updateEnrollments`. E.g. `{dryRun: true, IdScheme: 'CODE'}. Defaults to DHIS2 `default params` - * @param {{apiVersion: number,responseType: string}} [options] - Optional `flags` for the behavior of the `updateEnrollments` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}` - * @param {function} [callback] - Optional callback to handle the response - * @returns {Operation} - * @example <caption>- Example `expression.js` of `updateEnromments`</caption> - * updateEnrollments('PVqUD2hvU4E', state.data); - */ - - -function updateEnrollments(path, data, params, options, callback) { - return function (state) { - options = (0, _languageCommon.expandReferences)(options)(state); - if (options) options.operationName = 'updateEnrollments';else { - options = { - operationName: 'updateEnrollments' - }; - } - return update('enrollments', path, data, params, options, callback)(state); - }; -} -/** - * Cancel a DHIS2 Enrollment - * - To cancel an existing enrollment, you should supply the `enrollment identifier`(`enrollemt-id`) - * @public - * @function - * @param {string} enrollmentId - The `enrollment-id` of the enrollment you wish to cancel - * @param {Object} [params] - Optional `import` parameters for `cancelEnrollment`. E.g. `{dryRun: true, IdScheme: 'CODE'}. Defaults to DHIS2 `default params` - * @param {{apiVersion: number,responseType: string}} [options] - Optional `flags` for the behavior of the `cancelEnrollment` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}` - * @param {function} [callback] - Optional callback to handle the response - * @returns {Operation} - * @example <caption>- Example `expression.js` of `cancelEnrollment`</caption> - * cancelEnrollments('PVqUD2hvU4E'); - */ - - -function cancelEnrollment(enrollmentId, params, options, callback) { - return function (state) { - enrollmentId = (0, _languageCommon.expandReferences)(enrollmentId)(state); - options = (0, _languageCommon.expandReferences)(options)(state); - if (options) options.operationName = 'cancelEnrollment';else { - options = { - operationName: 'cancelEnrollment' - }; - } - var path = "".concat(enrollmentId, "/cancelled"); - return update('enrollments', path, null, params, options, callback)(state); - }; -} -/** - * Complete a DHIS2 Enrollment - * - To complete an existing enrollment, you should supply the `enrollment identifier`(`enrollemt-id`) - * @public - * @function - * @param {string} enrollmentId - The `enrollment-id` of the enrollment you wish to cancel - * @param {Object} [params] - Optional `import` parameters for `completeEnrollment`. E.g. `{dryRun: true, IdScheme: 'CODE'}. Defaults to DHIS2 `default params` - * @param {{apiVersion: number,responseType: string}} [options] - Optional `flags` for the behavior of the `completeEnrollment` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}` - * @param {function} [callback] - Optional callback to handle the response - * @returns {Operation} - * @example <caption>- Example `expression.js` of `completeEnrollment`</caption> - * completeEnrollment('PVqUD2hvU4E'); - */ - - -function completeEnrollment(enrollmentId, params, options, callback) { - return function (state) { - enrollmentId = (0, _languageCommon.expandReferences)(enrollmentId)(state); - options = (0, _languageCommon.expandReferences)(options)(state); - if (options) options.operationName = 'completeEnrollment';else { - options = { - operationName: 'completeEnrollment' - }; - } - var path = "".concat(enrollmentId, "/completed"); - return update('enrollments', path, null, params, options, callback)(state); - }; -} -/** - * Get DHIS2 Relationships(links) between two entities in tracker. These entities can be tracked entity instances, enrollments and events. - * - All the tracker operations, `getTEIs`, `getEnrollments` and `getEvents` also list their relationships if requested in the `field` filter. - * - To list all relationships, this requires you to provide the UID of the trackedEntityInstance, Enrollment or event that you want to list all the relationships for. - * @public - * @function - * @param {Object} params - `Query` parameters for `getRelationships`. See examples {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html#relationships here} - * @param {{apiVersion: number,responseType: string}} [options] - Optional `flags` for the behavior of the `getRelationships` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}` - * @param {function} [callback] - Optional callback to handle the response - * @returns {Operation} - * @example <caption>- A query for `all relationships` associated with a `specific tracked entity instance` can look like this:</caption> - * getRelationships({ tei: 'F8yKM85NbxW', fields: '*' }); - */ - - -function getRelationships(params, options, callback) { - return function (state) { - options = (0, _languageCommon.expandReferences)(options)(state); - if (options) options.operationName = 'getRelationships';else { - options = { - operationName: 'getRelationships' - }; - } - return getData('relationships', params, options, callback)(state); - }; -} -/** - * Get DHIS2 Data Values. - * - This operation retrives data values from DHIS2 Web API by interacting with the `dataValueSets` resource - * - Data values can be retrieved in XML, JSON and CSV format. - * @public - * @function - * @param {Object} params - `Query` parameters for `getDataValues`. E.g. `{dataset: 'pBOMPrpg1QX', limit: 3, period: 2021, orgUnit: 'DiszpKrYNg8'} Run `discover` or see {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html#data-values DHIS2 API docs} for available `Data Value Set Query Parameters`. - * @param {{apiVersion: number,responseType: string}} [options] - Optional `options` for `getDataValues` operation. Defaults to `{apiVersion: state.configuration.apiVersion, responseType: 'json'}` - * @param {function} [callback] - Optional `callback` to handle the response - * @returns {Operation} - * @example <caption>- Example getting **two** `data values` associated with a specific `orgUnit`, `dataSet`, and `period `</caption> - * getDataValues({ + * @example <caption>a dataElementGroup</caption> + * update('dataElementGroups', 'QrprHT61XFk', { + * name: 'Data Element Group 1', + * dataElements: [], + * }); + * @example <caption>a dataElementGroupSet</caption> + * update('dataElementGroupSets', 'VxWloRvAze8', { + * name: 'Data Element Group Set 4', + * dataDimension: true, + * shortName: 'DEGS4', + * dataElementGroups: [], + * }); + * @example <caption>a dataValueSet</caption> + * update('dataValueSets', 'AsQj6cDsUq4', { + * dataElement: 'f7n9E0hX8qk', + * period: '201401', * orgUnit: 'DiszpKrYNg8', - * period: '202010', - * dataSet: 'pBOMPrpg1QX', - * limit: 2, + * value: '12', * }); - */ - - -function getDataValues(params, options, callback) { - return function (state) { - options = (0, _languageCommon.expandReferences)(options)(state); - if (options) options.operationName = 'getDataValues';else { - options = { - operationName: 'getDataValues' - }; - } - return getData('dataValueSets', params, options, callback)(state); - }; -} -/** - * Create DHIS2 Data Values - * - This is used to send aggregated data to DHIS2 - * - A data value set represents a set of data values which have a relationship, usually from being captured off the same data entry form. - * - To send a set of related data values sharing the same period and organisation unit, we need to identify the period, the data set, the org unit (facility) and the data elements for which to report. - * - You can also use this operation to send large bulks of data values which don't necessarily are logically related. - * - To send data values that are not linked to a `dataSet`, you do not need to specify the dataSet and completeDate attributes. Instead, you will specify the period and orgUnit attributes on the individual data value elements instead of on the outer data value set element. This will enable us to send data values for various periods and organisation units - * @public - * @function - * @param {object} data - The `data values` to upload or create. See example shape. - * @param {{apiVersion: number,responseType: string}} [options] - Optional `flags` for the behavior of the `createDataVaues` operation. - * @param {object} [params] - Optional `import` parameters for `createDataValues`. E.g. `{dryRun: true, IdScheme: 'CODE'}. Defaults to DHIS2 `default params`. Run `discover` or visit {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html#data-values DHIS2 Docs API} to learn about available data values import parameters. - * @param {function} [callback] - Optional callback to handle the response - * @returns {Operation} - * @example <caption>- Example `expression.js` of `createDataValues` for sending a set of related data values sharing the same period and organisation unit</caption> - * createDataValues({ + * @example <caption>a dataValueSet with related dataValues</caption> + * update('dataValueSets', 'Ix2HsbDMLea', { * dataSet: 'pBOMPrpg1QX', * completeDate: '2014-02-03', * period: '201401', @@ -978,50 +473,147 @@

Source: Adaptor.js

* }, * ], * }); + * @example <caption>a single enrollment</caption> + * update('enrollments', 'CmsHzercTBa' { + * trackedEntityInstance: 'bmshzEacgxa', + * orgUnit: 'TSyzvBiovKh', + * program: 'gZBxv9Ujxg0', + * enrollmentDate: '2013-10-17', + * incidentDate: '2013-10-17', + * }); */ -function createDataValues(data, options, params, callback) { - return function (state) { +function update(resourceType, path, data, options = {}, callback = false) { + return state => { + console.log(`Preparing update operation...`); + resourceType = (0, _languageCommon.expandReferences)(resourceType)(state); + path = (0, _languageCommon.expandReferences)(path)(state); + data = (0, _languageCommon.expandReferences)(data)(state); options = (0, _languageCommon.expandReferences)(options)(state); - if (options) options.operationName = 'createDataValues';else { - options = { - operationName: 'createDataValues' - }; - } - return create('dataValueSets', data, options, params, callback)(state); + const { + params, + requestConfig + } = options; + const { + configuration + } = state; + return (0, _Client.request)(configuration, { + method: 'put', + url: (0, _Utils.generateUrl)(configuration, options, resourceType, path), + params, + data, + ...requestConfig + }).then(result => { + _Utils.Log.success(`Updated ${resourceType} at ${path}`); + + return (0, _Utils.handleResponse)(result, state, callback); + }); }; } /** - * Generate valid, random DHIS2 identifiers - * - Useful for client generated Ids compatible with DHIS2 + * Get data. Generic helper method for getting data of any kind from DHIS2. + * - This can be used to get `DataValueSets`,`events`,`trackedEntityInstances`,`etc.` * @public * @function - * @param {{apiVersion: number,limit: number,responseType: string}} [options] - Optional `options` for `generateDhis2UID` operation. Defaults to `{apiVersion: state.configuration.apiVersion,limit: 1,responseType: 'json'}` - * @param {function} [callback] - Callback to handle response - * @returns {Operation} - * @example <caption>Example generating `three UIDs` from the DHIS2 server</caption> - * generateDhis2UID({limit: 3}); + * @param {string} resourceType - The type of resource to get(use its `plural` name). E.g. `dataElements`, `trackedEntityInstances`,`organisationUnits`, etc. + * @param {Object} query - A query object that will limit what resources are retrieved when converted into request params. + * @param {Object} [options] - Optional `options` to define URL parameters via params beyond filters, request configuration (e.g. `auth`) and DHIS2 api version to use. + * @param {function} [callback] - Optional callback to handle the response + * @returns {Operation} state + * @example <caption>all data values for the 'pBOMPrpg1QX' dataset</caption> + * get('dataValueSets', { + * dataSet: 'pBOMPrpg1QX', + * orgUnit: 'DiszpKrYNg8', + * period: '201401', + * fields: '*', + * }); + * @example <caption>all programs for an organization unit</caption> + * get('programs', { orgUnit: 'TSyzvBiovKh', fields: '*' }); + * @example <caption>a single tracked entity instance by a unique external ID</caption> + * get('trackedEntityInstances', { + * ou: 'DiszpKrYNg8', + * filter: ['flGbXLXCrEo:Eq:124', 'w75KJ2mc4zz:Eq:John'], + * }); */ -function generateDhis2UID(options, callback) { - return function (state) { - var _options$limit, _options3, _options4; - +function get(resourceType, query, options = {}, callback = false) { + return state => { + console.log('Preparing get operation...'); + resourceType = (0, _languageCommon.expandReferences)(resourceType)(state); + query = (0, _languageCommon.expandReferences)(query)(state); options = (0, _languageCommon.expandReferences)(options)(state); - if (options) options.operationName = 'generateDhis2UID';else { - options = { - operationName: 'generateDhis2UID' - }; - } - var limit = { - limit: (_options$limit = (_options3 = options) === null || _options3 === void 0 ? void 0 : _options3.limit) !== null && _options$limit !== void 0 ? _options$limit : 1 - }; - (_options4 = options) === null || _options4 === void 0 ? true : delete _options4.limit; - return getData('system/id', limit, options, callback)(state); + const { + params, + requestConfig + } = options; + const { + configuration + } = state; + return (0, _Client.request)(configuration, { + method: 'get', + url: (0, _Utils.generateUrl)(configuration, options, resourceType), + params: { ...query, + ...params + }, + responseType: 'json', + ...requestConfig + }).then(result => { + _Utils.Log.success(`Retrieved ${resourceType}`); + + return (0, _Utils.handleResponse)(result, state, callback); + }); }; -} +} // /** +// * Upsert a record. A generic helper function used to atomically either insert a row, or on the basis of the row already existing, UPDATE that existing row instead. +// * @public +// * @function +// * @param {string} resourceType - The type of a resource to `insert` or `update`. E.g. `trackedEntityInstances` +// * @param {Object} data - The update data containing new values +// * @param {{replace:boolean, apiVersion: number,strict: boolean,responseType: string}} [options] - `Optional` options for `upsertTEI` operation. Defaults to `{replace: false, apiVersion: state.configuration.apiVersion,strict: true,responseType: 'json'}`. +// * @param {function} [callback] - Optional callback to handle the response +// * @throws {RangeError} - Throws range error +// * @returns {Operation} +// * @example <caption>Example `expression.js` of upsert</caption> +// * upsert( +// * 'trackedEntityInstances', +// * { +// * attributeId: 'lZGmxYbs97q', +// * attributeValue: state => +// * state.data.attributes.find(obj => obj.attribute === 'lZGmxYbs97q') +// * .value, +// * }, +// * state.data, +// * { ou: 'TSyzvBiovKh' } +// * ); +// */ +// export function upsert(resourceType, data, options = {}, callback = false) { +// return state => { +// console.log(`Preparing upsert via 'get' then 'create' OR 'update'...`); +// return get( +// resourceType, +// data +// )(state).then(resp => { +// const resources = resp.data[resourceType]; +// if (resources.length > 1) { +// throw new RangeError( +// `Cannot upsert on Non-unique attribute. The operation found more than one records for your request.` +// ); +// } else if (resources.length <= 0) { +// return create(resourceType, data, options, callback)(state); +// } else { +// const pathName = +// resourceType === 'trackedEntityInstances' +// ? 'trackedEntityInstance' +// : 'id'; +// const path = resources[0][pathName]; +// return update(resourceType, path, data, options, callback)(state); +// } +// }); +// }; +// } + /** * Discover `DHIS2` `api` `endpoint` `query parameters` and allowed `operators` for a given resource's endpoint. * @public @@ -1029,33 +621,32 @@

Source: Adaptor.js

* @param {string} httpMethod - The HTTP to inspect parameter usage for a given endpoint, e.g., `get`, `post`,`put`,`patch`,`delete` * @param {string} endpoint - The path for a given endpoint. E.g. `/trackedEntityInstances` or `/dataValueSets` * @returns {Operation} - * @example <caption>Example getting a list of `parameters allowed` on a given `endpoint` for specific `http method`</caption> + * @example <caption>a list of parameters allowed on a given endpoint for specific http method</caption> * discover('post', '/trackedEntityInstances') */ function discover(httpMethod, endpoint) { - return function (state) { - _Utils.Log.info("Discovering query/import parameters for ".concat(_Utils.COLORS.FgGreen).concat(httpMethod).concat(_Utils.ESCAPE, " on ").concat(_Utils.COLORS.FgGreen).concat(endpoint).concat(_Utils.ESCAPE)); - - return _axios["default"].get('https://dhis2.github.io/dhis2-api-specification/spec/metadata_openapi.json', { - transformResponse: [function (data) { - var tempData = JSON.parse(data); - var filteredData = tempData.paths[endpoint][httpMethod]; - return _objectSpread({}, filteredData, { - parameters: filteredData.parameters.reduce(function (acc, currentValue) { - var index = currentValue['$ref'].lastIndexOf('/') + 1; - var paramRef = currentValue['$ref'].slice(index); - var param = tempData.components.parameters[paramRef]; + return state => { + console.log(`Discovering query/import parameters for ${httpMethod} on ${endpoint}`); + return _axios.default.get('https://dhis2.github.io/dhis2-api-specification/spec/metadata_openapi.json', { + transformResponse: [data => { + let tempData = JSON.parse(data); + let filteredData = tempData.paths[endpoint][httpMethod]; + return { ...filteredData, + parameters: filteredData.parameters.reduce((acc, currentValue) => { + let index = currentValue['$ref'].lastIndexOf('/') + 1; + let paramRef = currentValue['$ref'].slice(index); + let param = tempData.components.parameters[paramRef]; if (param.schema['$ref']) { - var schemaRefIndex = param.schema['$ref'].lastIndexOf('/') + 1; - var schemaRef = param.schema['$ref'].slice(schemaRefIndex); + let schemaRefIndex = param.schema['$ref'].lastIndexOf('/') + 1; + let schemaRef = param.schema['$ref'].slice(schemaRefIndex); param.schema = tempData.components.schemas[schemaRef]; } param.schema = JSON.stringify(param.schema); - var descIndex; + let descIndex; if ((0, _lodash.indexOf)(param.description, ',') === -1 && (0, _lodash.indexOf)(param.description, '.') > -1) descIndex = (0, _lodash.indexOf)(param.description, '.');else if ((0, _lodash.indexOf)(param.description, ',') > -1 && (0, _lodash.indexOf)(param.description, '.') > -1) { descIndex = (0, _lodash.indexOf)(param.description, '.') < (0, _lodash.indexOf)(param.description, ',') ? (0, _lodash.indexOf)(param.description, '.') : (0, _lodash.indexOf)(param.description, ','); } else { @@ -1065,830 +656,162 @@

Source: Adaptor.js

acc[paramRef] = param; return acc; }, {}) - }); + }; }] - }).then(function (result) { + }).then(result => { var _result$data$descript; - _Utils.Log.info("\t=======================================================================================\n\tQuery Parameters for ".concat(_Utils.COLORS.FgGreen).concat(httpMethod).concat(_Utils.ESCAPE, " on ").concat(_Utils.COLORS.FgGreen).concat(endpoint).concat(_Utils.ESCAPE, " [").concat((_result$data$descript = result.data.description) !== null && _result$data$descript !== void 0 ? _result$data$descript : '<description_missing>', "]\n\t=======================================================================================")); - + console.log(`\t=======================================================================================\n\tQuery Parameters for ${httpMethod} on ${endpoint} [${(_result$data$descript = result.data.description) !== null && _result$data$descript !== void 0 ? _result$data$descript : '<description_missing>'}]\n\t=======================================================================================`); console.table(result.data.parameters, ['in', 'required', 'description']); console.table(result.data.parameters, ['schema']); - console.log("=========================================Responses===============================\n".concat((0, _Utils.prettyJson)(result.data.responses), "\n=======================================================================================")); - return _objectSpread({}, state, { + console.log(`=========================================Responses===============================\n${(0, _Utils.prettyJson)(result.data.responses)}\n=======================================================================================`); + return { ...state, data: result.data - }); - }); - }; -} -/** - * Get analytical, aggregated data - * - The analytics resource is powerful as it lets you query and retrieve data aggregated along all available data dimensions. - * - For instance, you can ask the analytics resource to provide the aggregated data values for a set of data elements, periods and organisation units. - * - Also, you can retrieve the aggregated data for a combination of any number of dimensions based on data elements and organisation unit group sets. - * @public - * @function - * @param {Object} params - Analytics `query parameters`, e.g. `{dx: 'fbfJHSPpUQD;cYeuwXTCPkU',filters: ['pe:2014Q1;2014Q2','ou:O6uvpzGd5pu;lc3eMKXaEfw']}`. Run `discover` or visit {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html#analytics DHIS2 API docs} to get the params available. - * @param {{apiVersion: number,responseType: string}}[options] - `Optional` options for `getAnalytics` operation. Defaults to `{apiVersion: state.configuration.apiVersion, responseType: 'json'}`. - * @param {function} [callback] - Callback to handle response - * @returns {Operation} - * @example <caption>Example getting only records where the data value is greater or equal to 6500 and less than 33000</caption> - * getAnalytics({ - * dimensions: [ - * 'dx:fbfJHSPpUQD;cYeuwXTCPkU', - * 'pe:2014', - * 'ou:O6uvpzGd5pu;lc3eMKXaEfw', - * ], - * measureCriteria: 'GE:6500;LT:33000', - * }); - */ - - -function getAnalytics(params, options, callback) { - return function (state) { - options = (0, _languageCommon.expandReferences)(options)(state); - if (options) options.operationName = 'getAnalytics';else { - options = { - operationName: 'getAnalytics' }; - } - return getData("analytics", params, options, callback)(state); - }; -} -/** - * Get DHIS2 api resources - * @public - * @function - * @param {Object} [params] - The `optional` query parameters for this endpoint. E.g `{filter: 'singular:like:attribute'}`. - * @param {{filter: string, fields: string, responseType: string}} [options] - The `optional` options, specifiying the filter expression. E.g. `singular:eq:attribute`. - * @param {function} [callback] - The `optional callback function that will be called to handle data returned by this function. - * @returns {Operation} - * @example <caption>Example getting a resource named `attribute`, in `xml` format, returning all the fields</caption> - * getResources('dataElement', { - * filter: 'singular:eq:attribute', - * fields: '*', - * responseType: 'xml', - * }); - */ - - -function getResources(params, options, callback) { - return function (state) { - var _options$responseType, _options5, _params, _CONTENT_TYPES$respon; - - params = (0, _languageCommon.expandReferences)(params)(state); - options = (0, _languageCommon.expandReferences)(options)(state); - var operationName = 'getResources'; - var _state$configuration3 = state.configuration, - username = _state$configuration3.username, - password = _state$configuration3.password, - hostUrl = _state$configuration3.hostUrl; - var responseType = (_options$responseType = (_options5 = options) === null || _options5 === void 0 ? void 0 : _options5.responseType) !== null && _options$responseType !== void 0 ? _options$responseType : 'json'; - var filter = (_params = params) === null || _params === void 0 ? void 0 : _params.filter; - var queryParams = params; - var headers = { - Accept: (_CONTENT_TYPES$respon = _Utils.CONTENT_TYPES[responseType]) !== null && _CONTENT_TYPES$respon !== void 0 ? _CONTENT_TYPES$respon : 'application/json' - }; - var path = '/resources'; - var url = (0, _Utils.buildUrl)(path, hostUrl, null, false); - - var transformResponse = function transformResponse(data, headers) { - if (filter) { - var _headers$contentType, _headers$contentType2; - - if (((_headers$contentType = (_headers$contentType2 = headers['content-type']) === null || _headers$contentType2 === void 0 ? void 0 : _headers$contentType2.split(';')[0]) !== null && _headers$contentType !== void 0 ? _headers$contentType : null) === _Utils.CONTENT_TYPES.json) { - var tempData = JSON.parse(data); - return _objectSpread({}, tempData, { - resources: _Utils.applyFilter.apply(void 0, [tempData.resources].concat(_toConsumableArray((0, _Utils.parseFilter)(filter)))) - }); - } else { - _Utils.Log.warn('Filters on this resource are only supported for json content types. Skipping filtering ...'); - } - } - - return data; - }; - - (0, _Utils.logOperation)(operationName); - (0, _Utils.logWaitingForServer)(url, queryParams); - (0, _Utils.warnExpectLargeResult)(queryParams, url); - return _axios["default"].request({ - url: url, - method: 'GET', - auth: { - username: username, - password: password - }, - responseType: responseType, - headers: headers, - params: queryParams, - transformResponse: transformResponse - }).then(function (result) { - _Utils.Log.info("".concat(_Utils.COLORS.FgGreen).concat(operationName, " succeeded").concat(_Utils.ESCAPE, ". The result of this operation will be in ").concat(operationName, "state.data").concat(_Utils.ESCAPE, " or in your ").concat(operationName, "callback").concat(_Utils.ESCAPE, ".")); - - if (callback) return callback((0, _languageCommon.composeNextState)(state, result.data)); - return (0, _languageCommon.composeNextState)(state, result.data); }); }; } /** - * Get schema of a given resource type, in any data format supported by DHIS2 - * @public - * @function - * @param {string} resourceType - The type of resource to be updated(`singular` version of the `resource name`). E.g. `dataElement`, `organisationUnit`, etc. Run `getResources` to see available resources and their corresponding `singular` names. - * @param {Object} params - Optional `query parameters` for the `getSchema` operation. e.g. `{ fields: 'properties' ,skipPaging: true}`. Run`discover` or See {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html#metadata-export-examples DHIS2 API Docs} - * @param {{apiVersion: number,resourceType: string}} [options] - Optional options for `getSchema` method. Defaults to `{apiVersion: state.configuration.apiVersion, responseType: 'json'}` - * @param {function} [callback] - Optional `callback` to handle the response - * @returns {Operation} - * @example <caption>Example getting the `schema` for `dataElement` in XML</caption> - * getSchema('dataElement', '{ fields: '*' }, { responseType: 'xml' }); - */ - - -function getSchema(resourceType, params, options, callback) { - return function (state) { - var _options$responseType2, _options6, _params2, _params3, _options$apiVersion2, _options7, _CONTENT_TYPES$respon2, _resourceType; - - resourceType = (0, _languageCommon.expandReferences)(resourceType)(state); - params = (0, _languageCommon.expandReferences)(params)(state); - options = (0, _languageCommon.expandReferences)(options)(state); - var operationName = 'getSchema'; - var _state$configuration4 = state.configuration, - username = _state$configuration4.username, - password = _state$configuration4.password, - hostUrl = _state$configuration4.hostUrl; - var responseType = (_options$responseType2 = (_options6 = options) === null || _options6 === void 0 ? void 0 : _options6.responseType) !== null && _options$responseType2 !== void 0 ? _options$responseType2 : 'json'; - var filters = (_params2 = params) === null || _params2 === void 0 ? void 0 : _params2.filters; - (_params3 = params) === null || _params3 === void 0 ? true : delete _params3.filters; - var queryParams = new URLSearchParams(params); - filters === null || filters === void 0 ? void 0 : filters.map(function (f) { - return queryParams.append('filter', f); - }); - var apiVersion = (_options$apiVersion2 = (_options7 = options) === null || _options7 === void 0 ? void 0 : _options7.apiVersion) !== null && _options$apiVersion2 !== void 0 ? _options$apiVersion2 : state.configuration.apiVersion; - var headers = { - Accept: (_CONTENT_TYPES$respon2 = _Utils.CONTENT_TYPES[responseType]) !== null && _CONTENT_TYPES$respon2 !== void 0 ? _CONTENT_TYPES$respon2 : 'application/json' - }; - var url = (0, _Utils.buildUrl)("/schemas/".concat((_resourceType = resourceType) !== null && _resourceType !== void 0 ? _resourceType : ''), hostUrl, apiVersion); - (0, _Utils.logOperation)(operationName); - (0, _Utils.logApiVersion)(apiVersion); - (0, _Utils.logWaitingForServer)(url, queryParams); - (0, _Utils.warnExpectLargeResult)(resourceType, url); - return _axios["default"].request({ - method: 'GET', - url: url, - auth: { - username: username, - password: password - }, - responseType: responseType, - params: queryParams, - headers: headers - }).then(function (result) { - _Utils.Log.info("".concat(_Utils.COLORS.FgGreen).concat(operationName, " succeeded").concat(_Utils.ESCAPE, ". The result of this operation will be in ").concat(operationName, "state.data").concat(_Utils.ESCAPE, " or in your ").concat(operationName, "callback").concat(_Utils.ESCAPE, ".")); - - if (callback) return callback((0, _languageCommon.composeNextState)(state, result.data)); - return (0, _languageCommon.composeNextState)(state, result.data); - }); - }; -} -/** - * Get data. Generic helper method for getting data of any kind from DHIS2. - * - This can be used to get `DataValueSets`,`events`,`trackedEntityInstances`,`etc.` - * @public - * @function - * @param {string} resourceType - The type of resource to get(use its `plural` name). E.g. `dataElements`, `trackedEntityInstances`,`organisationUnits`, etc. - * @param {Object} [params] - Optional `query parameters` e.g. `{ou: 'DiszpKrYNg8'}`. Run `discover` or see {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html DHIS2 docs} for more details on which params to use for a given type of resource. - * @param {{apiVersion: number,operationName: string,responseType: string}}[options] - `Optional` options for `getData` operation. Defaults to `{operationName: 'getData', apiVersion: state.configuration.apiVersion, responseType: 'json'}`. - * @param {function} [callback] - Optional callback to handle the response - * @returns {Operation} state - * @example <caption>Example getting one `trackedEntityInstance` with `Id` 'dNpxRu1mWG5' for a given `orgUnit(DiszpKrYNg8)`</caption> - * getData('trackedEntityInstances', { - * fields: '*', - * ou: 'DiszpKrYNg8', - * entityType: 'nEenWmSyUEp', - * trackedEntityInstance: 'dNpxRu1mWG5', - * }); - */ - - -function getData(resourceType, params, options, callback) { - return function (state) { - var _options$operationNam, _options8, _options$responseType3, _options9, _params4, _params5, _params6, _options$apiVersion3, _options10, _CONTENT_TYPES$respon3; - - resourceType = (0, _languageCommon.expandReferences)(resourceType)(state); - params = (0, _languageCommon.expandReferences)(params)(state); - options = (0, _languageCommon.expandReferences)(options)(state); - var operationName = (_options$operationNam = (_options8 = options) === null || _options8 === void 0 ? void 0 : _options8.operationName) !== null && _options$operationNam !== void 0 ? _options$operationNam : 'getData'; - var _state$configuration5 = state.configuration, - username = _state$configuration5.username, - password = _state$configuration5.password, - hostUrl = _state$configuration5.hostUrl; - var responseType = (_options$responseType3 = (_options9 = options) === null || _options9 === void 0 ? void 0 : _options9.responseType) !== null && _options$responseType3 !== void 0 ? _options$responseType3 : 'json'; - var filters = (_params4 = params) === null || _params4 === void 0 ? void 0 : _params4.filters; - var dimensions = (_params5 = params) === null || _params5 === void 0 ? void 0 : _params5.dimensions; - (_params6 = params) === null || _params6 === void 0 ? true : delete _params6.filters; - var queryParams = new URLSearchParams(params); - filters === null || filters === void 0 ? void 0 : filters.map(function (f) { - return queryParams.append('filter', f); - }); - dimensions === null || dimensions === void 0 ? void 0 : dimensions.map(function (d) { - return queryParams.append('dimension', d); - }); - var apiVersion = (_options$apiVersion3 = (_options10 = options) === null || _options10 === void 0 ? void 0 : _options10.apiVersion) !== null && _options$apiVersion3 !== void 0 ? _options$apiVersion3 : state.configuration.apiVersion; - var headers = { - Accept: (_CONTENT_TYPES$respon3 = _Utils.CONTENT_TYPES[responseType]) !== null && _CONTENT_TYPES$respon3 !== void 0 ? _CONTENT_TYPES$respon3 : 'application/json' - }; - var url = (0, _Utils.buildUrl)("/".concat(resourceType), hostUrl, apiVersion); - (0, _Utils.logOperation)(operationName); - (0, _Utils.logApiVersion)(apiVersion); - (0, _Utils.logWaitingForServer)(url, queryParams); - (0, _Utils.warnExpectLargeResult)(resourceType, url); - return _axios["default"].request({ - method: 'GET', - url: url, - auth: { - username: username, - password: password - }, - responseType: responseType, - params: queryParams, - headers: headers - }).then(function (result) { - _Utils.Log.info("".concat(_Utils.COLORS.FgGreen).concat(operationName, " succeeded").concat(_Utils.ESCAPE, ". The result of this operation will be in ").concat(operationName, " ").concat(_Utils.COLORS.FgGreen, "state.data").concat(_Utils.ESCAPE, " or in your ").concat(_Utils.COLORS.FgGreen, "callback").concat(_Utils.ESCAPE, ".")); - - if (callback) return callback((0, _languageCommon.composeNextState)(state, result.data)); - return (0, _languageCommon.composeNextState)(state, result.data); - }); - }; -} -/** - * Get metadata. A generic helper function to get metadata records from a given DHIS2 instance - * @public - * @function - * @param {string[]} resources - Required. List of metadata resources to fetch. E.g. `['organisationUnits', 'attributes']` or like `'dataSets'` if you only want a single type of resource. See `getResources` to see the types of resources available. - * @param {Object} [params] - Optional `query parameters` e.g. `{filters: ['name:like:ANC'],fields:'*'}`. See `discover` or visit {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html#metadata-export DHIS2 API docs} - * @param {{apiVersion: number,operationName: string,resourceType: string}} [options] - Optional `options` for `getMetadata` operation. Defaults to `{operationName: 'getMetadata', apiVersion: state.configuration.apiVersion, responseType: 'json'}` - * @param {function} [callback] - Optional `callback` to handle the response - * @returns {Operation} - * @example <caption>Example getting a list of `data elements` and `indicators` where `name` includes the word **ANC**</caption> - * getMetadata(['dataElements', 'indicators'], { - * filters: ['name:like:ANC'], - * }); - */ - - -function getMetadata(resources, params, options, callback) { - return function (state) { - var _options$responseType4, _options11, _queryParams, _queryParams2, _options$apiVersion4, _options12, _CONTENT_TYPES$respon4; - - resources = (0, _languageCommon.expandReferences)(resources)(state); - params = (0, _languageCommon.expandReferences)(params)(state); - options = (0, _languageCommon.expandReferences)(options)(state); - var operationName = 'getMetadata'; - var _state$configuration6 = state.configuration, - username = _state$configuration6.username, - password = _state$configuration6.password, - hostUrl = _state$configuration6.hostUrl; - var responseType = (_options$responseType4 = (_options11 = options) === null || _options11 === void 0 ? void 0 : _options11.responseType) !== null && _options$responseType4 !== void 0 ? _options$responseType4 : 'json'; - - if (typeof resources === 'string') { - var res = {}; - res[resources] = true; - resources = res; - } else { - resources = resources.reduce(function (acc, currentValue) { - acc[currentValue] = true; - return acc; - }, {}); - } - - var queryParams = _objectSpread({}, resources, {}, params); - - var filters = (_queryParams = queryParams) === null || _queryParams === void 0 ? void 0 : _queryParams.filters; - (_queryParams2 = queryParams) === null || _queryParams2 === void 0 ? true : delete _queryParams2.filters; - queryParams = new URLSearchParams(queryParams); - filters === null || filters === void 0 ? void 0 : filters.map(function (f) { - return queryParams.append('filter', f); - }); - var apiVersion = (_options$apiVersion4 = (_options12 = options) === null || _options12 === void 0 ? void 0 : _options12.apiVersion) !== null && _options$apiVersion4 !== void 0 ? _options$apiVersion4 : state.configuration.apiVersion; - var headers = { - Accept: (_CONTENT_TYPES$respon4 = _Utils.CONTENT_TYPES[responseType]) !== null && _CONTENT_TYPES$respon4 !== void 0 ? _CONTENT_TYPES$respon4 : 'application/json' - }; - var url = (0, _Utils.buildUrl)('/metadata', hostUrl, apiVersion); - (0, _Utils.logOperation)(operationName); - (0, _Utils.logApiVersion)(apiVersion); - (0, _Utils.logWaitingForServer)(url, queryParams); - (0, _Utils.warnExpectLargeResult)(queryParams, url); - return _axios["default"].request({ - method: 'GET', - url: url, - auth: { - username: username, - password: password - }, - responseType: responseType, - params: queryParams, - headers: headers - }).then(function (result) { - _Utils.Log.info("".concat(_Utils.COLORS.FgGreen).concat(operationName, " succeeded").concat(_Utils.ESCAPE, ". The result of this operation will be in ").concat(_Utils.COLORS.FgGreen).concat(operationName, " state.data").concat(_Utils.ESCAPE, " or in your ").concat(_Utils.COLORS.FgGreen, "callback").concat(_Utils.ESCAPE, ".")); - - if (callback) return callback((0, _languageCommon.composeNextState)(state, result.data)); - return (0, _languageCommon.composeNextState)(state, result.data); - }); - }; -} -/** - * create data. A generic helper method to create a record of any kind in DHIS2 + * Patch a record. A generic helper function to send partial updates on one or more object properties. + * - You are not required to send the full body of object properties. + * - This is useful for cases where you don't want or need to update all properties on a object. * @public * @function - * @param {string} resourceType - Type of resource to create. E.g. `trackedEntityInstances` - * @param {Object} data - Data that will be used to create a given instance of resource - * @param {Object} [options] - Optional `options` to control the behavior of the `create` operation.` Defaults to `{operationName: 'create', apiVersion: null, responseType: 'json'}` - * @param {Object} [params] - Optional `import parameters` for a given a resource. E.g. `{dryRun: true, importStrategy: CREATE}` See {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html DHIS2 API documentation} or {@link discover}. Defauls to `DHIS2 default params` for a given resource type. + * @param {string} resourceType - The type of resource to be updated. E.g. `dataElements`, `organisationUnits`, etc. + * @param {string} path - The `id` or `path` to the `object` to be updated. E.g. `FTRrcoaog83` or `FTRrcoaog83/{collection-name}/{object-id}` + * @param {Object} data - Data to update. Include only the fields you want to update. E.g. `{name: "New Name"}` + * @param {Object} [options] - Optional configuration, including params for the update ({preheatCache: true, strategy: 'UPDATE', mergeMode: 'REPLACE'}). Defaults to `{operationName: 'patch', apiVersion: state.configuration.apiVersion, responseType: 'json'}` * @param {function} [callback] - Optional callback to handle the response * @returns {Operation} - * @example <caption>- Example `expression.js` of `create`</caption> - * create('events', { - * program: 'eBAyeGv0exc', - * orgUnit: 'DiszpKrYNg8', - * eventDate: date, - * status: 'COMPLETED', - * completedDate: date, - * storedBy: 'admin', - * coordinate: { - * latitude: 59.8, - * longitude: 10.9, - * }, - * dataValues: [ - * { - * dataElement: 'qrur9Dvnyt5', - * value: '33', - * }, - * { - * dataElement: 'oZg33kd9taw', - * value: 'Male', - * }, - * { - * dataElement: 'msodh3rEMJa', - * value: date, - * }, - * ], - * }); + * @example <caption>a dataElement</caption> + * patch('dataElements', 'FTRrcoaog83', { name: 'New Name' }); */ +// TODO: @Elias, can this be deleted in favor of update? How does DHIS2 handle PATCH vs PUT? +// I need to investigate on this. But I think DHIS2 forces to send all properties back when we do an update. If that's confirmed then this may be needed. -function create(resourceType, data, options, params, callback) { - return function (state) { - var _options$operationNam2, _options13, _options$responseType5, _options14, _params7, _params8, _options$apiVersion5, _options15, _CONTENT_TYPES$respon5; - +function patch(resourceType, path, data, options = {}, callback = false) { + return state => { + console.log('Preparing patch operation...'); resourceType = (0, _languageCommon.expandReferences)(resourceType)(state); - var body = (0, _languageCommon.expandReferences)(data)(state); + path = (0, _languageCommon.expandReferences)(path)(state); + data = (0, _languageCommon.expandReferences)(data)(state); options = (0, _languageCommon.expandReferences)(options)(state); - params = (0, _languageCommon.expandReferences)(params)(state); - var operationName = (_options$operationNam2 = (_options13 = options) === null || _options13 === void 0 ? void 0 : _options13.operationName) !== null && _options$operationNam2 !== void 0 ? _options$operationNam2 : 'create'; - var _state$configuration7 = state.configuration, - username = _state$configuration7.username, - password = _state$configuration7.password, - hostUrl = _state$configuration7.hostUrl; - var responseType = (_options$responseType5 = (_options14 = options) === null || _options14 === void 0 ? void 0 : _options14.responseType) !== null && _options$responseType5 !== void 0 ? _options$responseType5 : 'json'; - var filters = (_params7 = params) === null || _params7 === void 0 ? void 0 : _params7.filters; - (_params8 = params) === null || _params8 === void 0 ? true : delete _params8.filters; - var queryParams = new URLSearchParams(params); - var apiVersion = (_options$apiVersion5 = (_options15 = options) === null || _options15 === void 0 ? void 0 : _options15.apiVersion) !== null && _options$apiVersion5 !== void 0 ? _options$apiVersion5 : state.configuration.apiVersion; - var url = (0, _Utils.buildUrl)('/' + resourceType, hostUrl, apiVersion); - var headers = { - Accept: (_CONTENT_TYPES$respon5 = _Utils.CONTENT_TYPES[responseType]) !== null && _CONTENT_TYPES$respon5 !== void 0 ? _CONTENT_TYPES$respon5 : 'application/json', - 'Content-Type': 'application/json' - }; - (0, _Utils.logOperation)(operationName); - (0, _Utils.logApiVersion)(apiVersion); - (0, _Utils.logWaitingForServer)(url, queryParams); - (0, _Utils.warnExpectLargeResult)(resourceType, url); - return _axios["default"].request({ - method: 'POST', - url: url, - auth: { - username: username, - password: password - }, - params: queryParams, - data: body, - headers: headers - }).then(function (result) { - var _result$data$response, _result$data$response2; - - _Utils.Log.info("".concat(_Utils.COLORS.FgGreen).concat(operationName, " succeeded").concat(_Utils.ESCAPE, ". Created ").concat(resourceType, ": ").concat(_Utils.COLORS.FgGreen).concat(((_result$data$response = result.data.response) === null || _result$data$response === void 0 ? void 0 : _result$data$response.importSummaries) ? result.data.response.importSummaries[0].href : (_result$data$response2 = result.data.response) === null || _result$data$response2 === void 0 ? void 0 : _result$data$response2.reference).concat(_Utils.ESCAPE, ".\nSummary:\n").concat((0, _Utils.prettyJson)(result.data))); - - if (callback) return callback((0, _languageCommon.composeNextState)(state, result.data)); - return (0, _languageCommon.composeNextState)(state, result.data); + const { + params, + requestConfig + } = options; + const { + configuration + } = state; + return (0, _Client.request)(configuration, { + method: 'patch', + url: (0, _Utils.generateUrl)(configuration, options, resourceType, path), + params, + data, + ...requestConfig + }).then(result => { + _Utils.Log.success(`Patched ${resourceType} at ${path}`); + + return (0, _Utils.handleResponse)(result, state, callback); }); }; } /** - * Update data. A generic helper function to update a resource object of any type. - * - It requires to send `all required fields` or the `full body` + * Delete a record. A generic helper function to delete an object * @public * @function - * @param {string} resourceType - The type of resource to be updated. E.g. `dataElements`, `organisationUnits`, etc. - * @param {string} path - The `id` or `path` to the `object` to be updated. E.g. `FTRrcoaog83` or `FTRrcoaog83/{collection-name}/{object-id}` - * @param {Object} data - Data to update. It requires to send `all required fields` or the `full body`. If you want `partial updates`, use `patch` operation. - * @param {Object} [params] - Optional `update` parameters e.g. `{preheatCache: true, strategy: 'UPDATE', mergeMode: 'REPLACE'}`. Run `discover` or see {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html#create-update-parameters DHIS2 documentation} - * @param {{apiVersion: number,operationName: string,resourceType: string}} [options] - Optional options for update method. Defaults to `{operationName: 'update', apiVersion: state.configuration.apiVersion, responseType: 'json'}` - * @param {function} [callback] - Optional callback to handle the response + * @param {string} resourceType - The type of resource to be deleted. E.g. `trackedEntityInstances`, `organisationUnits`, etc. + * @param {string} path - Can be an `id` of an `object` or `path` to the `nested object` to `delete`. + * @param {Object} [data] - Optional. This is useful when you want to remove multiple objects from a collection in one request. You can send `data` as, for example, `{"identifiableObjects": [{"id": "IDA"}, {"id": "IDB"}, {"id": "IDC"}]}`. See more {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html#deleting-objects on DHIS2 API docs} + * @param {{apiVersion: number,operationName: string,resourceType: string}} [options] - Optional `options` for `del` operation including params e.g. `{preheatCache: true, strategy: 'UPDATE', mergeMode: 'REPLACE'}`. Run `discover` or see {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html#create-update-parameters DHIS2 documentation}. Defaults to `{operationName: 'delete', apiVersion: state.configuration.apiVersion, responseType: 'json'}` + * @param {function} [callback] - Optional callback to handle the response * @returns {Operation} - * @example <caption>Example `updating` a `data element`</caption> - * update('dataElements', 'FTRrcoaog83', - * { - * displayName: 'New display name', - * aggregationType: 'SUM', - * domainType: 'AGGREGATE', - * valueType: 'NUMBER', - * name: 'Accute Flaccid Paralysis (Deaths < 5 yrs)', - * shortName: 'Accute Flaccid Paral (Deaths < 5 yrs)', - * }); - * + * @example <caption>a tracked entity instance</caption> + * destroy('trackedEntityInstances', 'LcRd6Nyaq7T'); */ -function update(resourceType, path, data, params, options, callback) { - return function (state) { - var _options$operationNam3, _options16, _options$responseType6, _options17, _params9, _params10, _options$apiVersion6, _options18, _CONTENT_TYPES$respon6; - +function destroy(resourceType, path, data = null, options = {}, callback = false) { + return state => { + console.log('Preparing destroy operation...'); resourceType = (0, _languageCommon.expandReferences)(resourceType)(state); path = (0, _languageCommon.expandReferences)(path)(state); - var body = (0, _languageCommon.expandReferences)(data)(state); - params = (0, _languageCommon.expandReferences)(params)(state); + data = (0, _languageCommon.expandReferences)(data)(state); options = (0, _languageCommon.expandReferences)(options)(state); - var _state$configuration8 = state.configuration, - username = _state$configuration8.username, - password = _state$configuration8.password, - hostUrl = _state$configuration8.hostUrl; - var operationName = (_options$operationNam3 = (_options16 = options) === null || _options16 === void 0 ? void 0 : _options16.operationName) !== null && _options$operationNam3 !== void 0 ? _options$operationNam3 : 'update'; - var responseType = (_options$responseType6 = (_options17 = options) === null || _options17 === void 0 ? void 0 : _options17.responseType) !== null && _options$responseType6 !== void 0 ? _options$responseType6 : 'json'; - var filters = (_params9 = params) === null || _params9 === void 0 ? void 0 : _params9.filters; - (_params10 = params) === null || _params10 === void 0 ? true : delete _params10.filters; - var queryParams = new URLSearchParams(params); - filters === null || filters === void 0 ? void 0 : filters.map(function (f) { - return queryParams.append('filter', f); - }); - var apiVersion = (_options$apiVersion6 = (_options18 = options) === null || _options18 === void 0 ? void 0 : _options18.apiVersion) !== null && _options$apiVersion6 !== void 0 ? _options$apiVersion6 : state.configuration.apiVersion; - var url = (0, _Utils.buildUrl)('/' + resourceType + '/' + path, hostUrl, apiVersion); - var headers = { - Accept: (_CONTENT_TYPES$respon6 = _Utils.CONTENT_TYPES[responseType]) !== null && _CONTENT_TYPES$respon6 !== void 0 ? _CONTENT_TYPES$respon6 : 'application/json' - }; - (0, _Utils.logOperation)(operationName); - (0, _Utils.logApiVersion)(apiVersion); - (0, _Utils.logWaitingForServer)(url, queryParams); - (0, _Utils.warnExpectLargeResult)(resourceType, url); - return _axios["default"].request({ - method: 'PUT', - url: url, - auth: { - username: username, - password: password - }, - params: queryParams, - data: body, - headers: headers - }).then(function (result) { - _Utils.Log.info("".concat(_Utils.COLORS.FgGreen).concat(operationName, " succeeded").concat(_Utils.ESCAPE, ". Updated ").concat(resourceType, ".\nSummary:\n").concat((0, _Utils.prettyJson)(result.data))); - - if (callback) return callback((0, _languageCommon.composeNextState)(state, result.data)); - return (0, _languageCommon.composeNextState)(state, result.data); + const { + params, + requestConfig + } = options; + const { + configuration + } = state; + return (0, _Client.request)({ + method: 'delete', + url: (0, _Utils.generateUrl)(configuration, options, resourceType, path), + params, + data, + ...requestConfig + }).then(result => { + _Utils.Log.success(`Deleted ${resourceType} at ${path}`); + + return (0, _Utils.handleResponse)(result, state, callback); }); }; } /** - * Patch a record. A generic helper function to send partial updates on one or more object properties. - * - You are not required to send the full body of object properties. - * - This is useful for cases where you don't want or need to update all properties on a object. + * Gets an attribute value by its case-insensitive display name * @public + * @example + * findAttributeValue(state.data.trackedEntityInstances[0], 'first name') * @function - * @param {string} resourceType - The type of resource to be updated. E.g. `dataElements`, `organisationUnits`, etc. - * @param {string} path - The `id` or `path` to the `object` to be updated. E.g. `FTRrcoaog83` or `FTRrcoaog83/{collection-name}/{object-id}` - * @param {Object} data - Data to update. Include only the fields you want to update. E.g. `{name: "New Name"}` - * @param {Object} [params] - Optional `update` parameters e.g. `{preheatCache: true, strategy: 'UPDATE', mergeMode: 'REPLACE'}`. Run `discover` or see {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html#create-update-parameters DHIS2 documentation} - * @param {{apiVersion: number,operationName: string,responseType: string}} [options] - Optional options for update method. Defaults to `{operationName: 'patch', apiVersion: state.configuration.apiVersion, responseType: 'json'}` - * @param {function} [callback] - Optional callback to handle the response - * @returns {Operation} - * @example <caption>Example `patching` a `data element`</caption> - * patch('dataElements', 'FTRrcoaog83', - * { - * name: 'New Name', - * }); + * @param {Object} trackedEntityInstance - A tracked entity instance (TEI) object + * @param {string} attributeDisplayName - The 'displayName' to search for in the TEI's attributes + * @returns {string} */ -function patch(resourceType, path, data, params, options, callback) { - return function (state) { - var _options$operationNam4, _options19, _options$responseType7, _options20, _queryParams3, _queryParams4, _options$apiVersion7, _options21, _CONTENT_TYPES$respon7; +function findAttributeValue(trackedEntityInstance, attributeDisplayName) { + var _trackedEntityInstanc, _trackedEntityInstanc2; - resourceType = (0, _languageCommon.expandReferences)(resourceType)(state); - path = (0, _languageCommon.expandReferences)(path)(state); - var body = (0, _languageCommon.expandReferences)(data)(state); - params = (0, _languageCommon.expandReferences)(params)(state); - options = (0, _languageCommon.expandReferences)(options)(state); - var operationName = (_options$operationNam4 = (_options19 = options) === null || _options19 === void 0 ? void 0 : _options19.operationName) !== null && _options$operationNam4 !== void 0 ? _options$operationNam4 : 'patch'; - var _state$configuration9 = state.configuration, - username = _state$configuration9.username, - password = _state$configuration9.password, - hostUrl = _state$configuration9.hostUrl; - var responseType = (_options$responseType7 = (_options20 = options) === null || _options20 === void 0 ? void 0 : _options20.responseType) !== null && _options$responseType7 !== void 0 ? _options$responseType7 : 'json'; - var queryParams = params; - var filters = (_queryParams3 = queryParams) === null || _queryParams3 === void 0 ? void 0 : _queryParams3.filters; - (_queryParams4 = queryParams) === null || _queryParams4 === void 0 ? true : delete _queryParams4.filters; - queryParams = new URLSearchParams(queryParams); - filters === null || filters === void 0 ? void 0 : filters.map(function (f) { - return queryParams.append('filter', f); - }); - var apiVersion = (_options$apiVersion7 = (_options21 = options) === null || _options21 === void 0 ? void 0 : _options21.apiVersion) !== null && _options$apiVersion7 !== void 0 ? _options$apiVersion7 : state.configuration.apiVersion; - var url = (0, _Utils.buildUrl)('/' + resourceType + '/' + path, hostUrl, apiVersion); - var headers = { - Accept: (_CONTENT_TYPES$respon7 = _Utils.CONTENT_TYPES[responseType]) !== null && _CONTENT_TYPES$respon7 !== void 0 ? _CONTENT_TYPES$respon7 : 'application/json' - }; - (0, _Utils.logOperation)(operationName); - (0, _Utils.logApiVersion)(apiVersion); - (0, _Utils.logWaitingForServer)(url, queryParams); - (0, _Utils.warnExpectLargeResult)(resourceType, url); - return _axios["default"].request({ - method: 'PATCH', - url: url, - auth: { - username: username, - password: password - }, - params: queryParams, - data: body, - headers: headers - }).then(function (result) { - var resultObject = { - status: result.status, - statusText: result.statusText - }; - - _Utils.Log.info("".concat(_Utils.COLORS.FgGreen).concat(operationName, " succeeded").concat(_Utils.ESCAPE, ". Updated ").concat(resourceType, ".\nSummary:\n").concat((0, _Utils.prettyJson)(resultObject))); - - if (callback) return callback((0, _languageCommon.composeNextState)(state, resultObject)); - return (0, _languageCommon.composeNextState)(state, resultObject); - }); - }; + return trackedEntityInstance === null || trackedEntityInstance === void 0 ? void 0 : (_trackedEntityInstanc = trackedEntityInstance.attributes) === null || _trackedEntityInstanc === void 0 ? void 0 : (_trackedEntityInstanc2 = _trackedEntityInstanc.find(a => (a === null || a === void 0 ? void 0 : a.displayName.toLowerCase()) == attributeDisplayName.toLowerCase())) === null || _trackedEntityInstanc2 === void 0 ? void 0 : _trackedEntityInstanc2.value; } /** - * Delete a record. A generic helper function to delete an object + * Converts an attribute ID and value into a DSHI2 attribute object * @public + * @example + * attr('w75KJ2mc4zz', 'Elias') * @function - * @param {string} resourceType - The type of resource to be deleted. E.g. `trackedEntityInstances`, `organisationUnits`, etc. - * @param {string} path - Can be an `id` of an `object` or `path` to the `nested object` to `delete`. - * @param {Object} [data] - Optional. This is useful when you want to remove multiple objects from a collection in one request. You can send `data` as, for example, `{"identifiableObjects": [{"id": "IDA"}, {"id": "IDB"}, {"id": "IDC"}]}`. See more {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html#deleting-objects on DHIS2 API docs} - * @param {Object} [params] - Optional `update` parameters e.g. `{preheatCache: true, strategy: 'UPDATE', mergeMode: 'REPLACE'}`. Run `discover` or see {@link https://docs.dhis2.org/2.34/en/dhis2_developer_manual/web-api.html#create-update-parameters DHIS2 documentation} - * @param {{apiVersion: number,operationName: string,resourceType: string}} [options] - Optional `options` for `del` operation. Defaults to `{operationName: 'delete', apiVersion: state.configuration.apiVersion, responseType: 'json'}` - * @param {function} [callback] - Optional callback to handle the response - * @returns {Operation} - * @example <caption>Example`deleting` a `tracked entity instance`</caption> - * del('trackedEntityInstances', 'LcRd6Nyaq7T'); + * @param {string} attribute - A tracked entity instance (TEI) attribute ID. + * @param {string} value - The value for that attribute. + * @returns {object} */ -function del(resourceType, path, data, params, options, callback) { - return function (state) { - var _options$operationNam5, _options22, _options$responseType8, _options23, _queryParams5, _queryParams6, _options$apiVersion8, _options24, _CONTENT_TYPES$respon8; - - resourceType = (0, _languageCommon.expandReferences)(resourceType)(state); - path = (0, _languageCommon.expandReferences)(path)(state); - var body = (0, _languageCommon.expandReferences)(data)(state); - params = (0, _languageCommon.expandReferences)(params)(state); - options = (0, _languageCommon.expandReferences)(options)(state); - var operationName = (_options$operationNam5 = (_options22 = options) === null || _options22 === void 0 ? void 0 : _options22.operationName) !== null && _options$operationNam5 !== void 0 ? _options$operationNam5 : 'delete'; - var _state$configuration10 = state.configuration, - username = _state$configuration10.username, - password = _state$configuration10.password, - hostUrl = _state$configuration10.hostUrl; - var responseType = (_options$responseType8 = (_options23 = options) === null || _options23 === void 0 ? void 0 : _options23.responseType) !== null && _options$responseType8 !== void 0 ? _options$responseType8 : 'json'; - var queryParams = params; - var filters = (_queryParams5 = queryParams) === null || _queryParams5 === void 0 ? void 0 : _queryParams5.filters; - (_queryParams6 = queryParams) === null || _queryParams6 === void 0 ? true : delete _queryParams6.filters; - queryParams = new URLSearchParams(queryParams); - filters === null || filters === void 0 ? void 0 : filters.map(function (f) { - return queryParams.append('filter', f); - }); - var apiVersion = (_options$apiVersion8 = (_options24 = options) === null || _options24 === void 0 ? void 0 : _options24.apiVersion) !== null && _options$apiVersion8 !== void 0 ? _options$apiVersion8 : state.configuration.apiVersion; - var headers = { - Accept: (_CONTENT_TYPES$respon8 = _Utils.CONTENT_TYPES[responseType]) !== null && _CONTENT_TYPES$respon8 !== void 0 ? _CONTENT_TYPES$respon8 : 'application/json' - }; - var url = (0, _Utils.buildUrl)('/' + resourceType + '/' + path, hostUrl, apiVersion); - (0, _Utils.logOperation)(operationName); - (0, _Utils.logApiVersion)(apiVersion); - (0, _Utils.logWaitingForServer)(url, queryParams); - (0, _Utils.warnExpectLargeResult)(resourceType, url); - return _axios["default"].request({ - method: 'DELETE', - url: url, - auth: { - username: username, - password: password - }, - params: queryParams, - data: body, - headers: headers - }).then(function (result) { - _Utils.Log.info("".concat(_Utils.COLORS.FgGreen).concat(operationName, " succeeded").concat(_Utils.ESCAPE, ". DELETED ").concat(resourceType, ".\nSummary:\n").concat((0, _Utils.prettyJson)(result.data))); - - if (callback) return callback((0, _languageCommon.composeNextState)(state, result.data)); - return (0, _languageCommon.composeNextState)(state, result.data); - }); +function attr(attribute, value) { + return { + attribute, + value }; } /** - * Upsert a record. A generic helper function used to atomically either insert a row, or on the basis of the row already existing, UPDATE that existing row instead. + * Converts a dataElement and value into a DSHI2 dataValue object * @public + * @example + * dv('f7n9E0hX8qk', 12) * @function - * @param {string} resourceType - The type of a resource to `insert` or `update`. E.g. `trackedEntityInstances` - * @param {{attributeId: string,attributeValue:any}} uniqueAttribute - An object containing a `attributeId` and `attributeValue` which will be used to uniquely identify the record - * @param {Object} data - The update data containing new values - * @param {Object} [params] - Optional `import` parameters e.g. `{ou: 'lZGmxYbs97q', filters: ['w75KJ2mc4zz:EQ:Jane']}` - * @param {{replace:boolean, apiVersion: number,strict: boolean,responseType: string}} [options] - `Optional` options for `upsertTEI` operation. Defaults to `{replace: false, apiVersion: state.configuration.apiVersion,strict: true,responseType: 'json'}`. - * @param {function} [callback] - Optional callback to handle the response - * @throws {RangeError} - Throws range error - * @returns {Operation} - * @example <caption>- Example `expression.js` of upsert</caption> - * upsert( - * 'trackedEntityInstances', - * { - * attributeId: 'lZGmxYbs97q', - * attributeValue: state => - * state.data.attributes.find(obj => obj.attribute === 'lZGmxYbs97q') - * .value, - * }, - * state.data, - * { ou: 'TSyzvBiovKh' } - * ); - * @todo Tweak/refine to mimic implementation based on the following inspiration: {@link https://sqlite.org/lang_upsert.html sqlite upsert} and {@link https://wiki.postgresql.org/wiki/UPSERT postgresql upsert} - * @todo Test implementation for upserting metadata - * @todo Test implementation for upserting data values - * @todo Implement the updateCondition + * @param {string} dataElement - A data element ID. + * @param {string} value - The value for that data element. + * @returns {object} */ -function upsert(resourceType, uniqueAttribute, data, params, options, callback) { - return function (state) { - var _options$operationNam6, _options25, _options$replace, _options26, _options$responseType9, _options27, _params11, _options$apiVersion9, _options28, _CONTENT_TYPES$respon9; - - resourceType = (0, _languageCommon.expandReferences)(resourceType)(state); - uniqueAttribute = (0, _languageCommon.expandReferences)(uniqueAttribute)(state); - var body = (0, _languageCommon.expandReferences)(data)(state); - params = (0, _languageCommon.expandReferences)(params)(state); - options = (0, _languageCommon.expandReferences)(options)(state); - var operationName = (_options$operationNam6 = (_options25 = options) === null || _options25 === void 0 ? void 0 : _options25.operationName) !== null && _options$operationNam6 !== void 0 ? _options$operationNam6 : 'upsert'; - var _state$configuration11 = state.configuration, - username = _state$configuration11.username, - password = _state$configuration11.password, - hostUrl = _state$configuration11.hostUrl; - var replace = (_options$replace = (_options26 = options) === null || _options26 === void 0 ? void 0 : _options26.replace) !== null && _options$replace !== void 0 ? _options$replace : false; - var responseType = (_options$responseType9 = (_options27 = options) === null || _options27 === void 0 ? void 0 : _options27.responseType) !== null && _options$responseType9 !== void 0 ? _options$responseType9 : 'json'; - var _uniqueAttribute = uniqueAttribute, - attributeId = _uniqueAttribute.attributeId, - attributeValue = _uniqueAttribute.attributeValue; - var filters = (_params11 = params) === null || _params11 === void 0 ? void 0 : _params11.filters; - delete params.filters; - var queryParams = new URLSearchParams(params); - filters === null || filters === void 0 ? void 0 : filters.map(function (f) { - return queryParams.append('filter', f); - }); - var op = resourceType === 'trackedEntityInstances' ? 'EQ' : 'eq'; - queryParams.append('filter', "".concat(attributeId, ":").concat(op, ":").concat(attributeValue)); - var apiVersion = (_options$apiVersion9 = (_options28 = options) === null || _options28 === void 0 ? void 0 : _options28.apiVersion) !== null && _options$apiVersion9 !== void 0 ? _options$apiVersion9 : state.configuration.apiVersion; - var url = (0, _Utils.buildUrl)('/' + resourceType, hostUrl, apiVersion); - var headers = { - Accept: (_CONTENT_TYPES$respon9 = _Utils.CONTENT_TYPES[responseType]) !== null && _CONTENT_TYPES$respon9 !== void 0 ? _CONTENT_TYPES$respon9 : 'application/json' - }; - (0, _Utils.logOperation)(operationName); - (0, _Utils.logApiVersion)(apiVersion); - (0, _Utils.logWaitingForServer)(url, queryParams); - (0, _Utils.warnExpectLargeResult)(resourceType, url); - - var getResouceName = function getResouceName() { - return _axios["default"].get(hostUrl + '/api/resources', { - auth: { - username: username, - password: password - }, - transformResponse: [function (data, headers) { - var filter = "plural:eq:".concat(resourceType); - - if (filter) { - var _headers$contentType3, _headers$contentType4; - - if (((_headers$contentType3 = (_headers$contentType4 = headers['content-type']) === null || _headers$contentType4 === void 0 ? void 0 : _headers$contentType4.split(';')[0]) !== null && _headers$contentType3 !== void 0 ? _headers$contentType3 : null) === _Utils.CONTENT_TYPES.json) { - var tempData = JSON.parse(data); - return _objectSpread({}, tempData, { - resources: _Utils.applyFilter.apply(void 0, [tempData.resources].concat(_toConsumableArray((0, _Utils.parseFilter)(filter)))) - }); - } else { - _Utils.Log.warn('Filters on this resource are only supported for json content types. Skipping filtering ...'); - } - } - - return data; - }] - }).then(function (result) { - return result.data.resources[0].singular; - }); - }; - - var findRecordsWithValueOnAttribute = function findRecordsWithValueOnAttribute() { - console.log(queryParams); - return _axios["default"].request({ - method: 'GET', - url: url, - auth: { - username: username, - password: password - }, - params: queryParams, - headers: headers - }); - }; - - _Utils.Log.info("Checking if a record exists that matches this filter: ".concat(_Utils.COLORS.FgGreen, "attribute{ id: ").concat(attributeId, ", value: ").concat(attributeValue, " }\x1B[0m ...")); - - return Promise.all([getResouceName(), findRecordsWithValueOnAttribute()]).then(function (_ref3) { - var _ref4 = _slicedToArray(_ref3, 2), - resourceName = _ref4[0], - recordsWithValue = _ref4[1]; - - var recordsWithValueCount = recordsWithValue.data[resourceType].length; - - if (recordsWithValueCount > 1) { - _Utils.Log.error(''); - - throw new RangeError("Cannot upsert on Non-unique attribute. The operation found more than one records with the same value of ".concat(attributeValue, " for ").concat(attributeId)); - } else if (recordsWithValueCount === 1) { - var _row1$id; - - // TODO - // Log.info( - // `Unique record found, proceeding to checking if attribute is NULLABLE ...` - // ); - // if (recordsWithNulls.data[resourceType].length > 0) { - // throw new Error( - // `Cannot upsert on Nullable attribute. The operation found records with a NULL value on ${attributeId}.` - // ); - // } - _Utils.Log.info("".concat(_Utils.COLORS.FgGreen, "Attribute has unique values").concat(_Utils.ESCAPE, ". Proceeding to ").concat(_Utils.COLORS.FgGreen).concat(replace ? 'replace' : 'merge').concat(_Utils.ESCAPE, " ...")); - - var row1 = recordsWithValue.data[resourceType][0]; - var useCustomPATCH = ['trackedEntityInstances'].includes(resourceType) ? true : false; - var method = replace ? 'PUT' : useCustomPATCH === true ? 'PUT' : 'PATCH'; - var id = (_row1$id = row1['id']) !== null && _row1$id !== void 0 ? _row1$id : row1[resourceName]; - var updateUrl = "".concat(url, "/").concat(id); - var payload = useCustomPATCH ? _objectSpread({}, row1, {}, body, { - attributes: [].concat(_toConsumableArray(row1.attributes), _toConsumableArray(body.attributes)) - }) : body; - return _axios["default"].request({ - method: method, - url: updateUrl, - auth: { - username: username, - password: password - }, - data: payload, - params: queryParams, - headers: headers - }).then(function (result) { - _Utils.Log.info("".concat(_Utils.COLORS.FgGreen).concat(operationName, " succeeded").concat(_Utils.ESCAPE, ". Updated ").concat(resourceName, ": ").concat(_Utils.COLORS.FgGreen).concat(updateUrl).concat(_Utils.ESCAPE, ".\nSummary:\n").concat((0, _Utils.prettyJson)(result.data))); - - if (callback) return callback((0, _languageCommon.composeNextState)(state, result.data)); - return (0, _languageCommon.composeNextState)(state, result.data); - }); - } else if (recordsWithValueCount === 0) { - _Utils.Log.info("".concat(_Utils.COLORS.FgGreen, "Existing record not found").concat(_Utils.ESCAPE, ", proceeding to ").concat(_Utils.COLORS.FgGreen, "CREATE(POST)").concat(_Utils.ESCAPE, " ...")); // We must delete the filter and ou params so the POST request is not interpreted as a GET request by the server - - - queryParams["delete"]('filter'); - queryParams["delete"]('ou'); - return _axios["default"].request({ - method: 'POST', - url: url, - auth: { - username: username, - password: password - }, - data: body, - params: queryParams, - headers: headers - }).then(function (result) { - var _result$data$response3; - - _Utils.Log.info("".concat(_Utils.COLORS.FgGreen).concat(operationName, " succeeded").concat(_Utils.ESCAPE, ". Created ").concat(resourceName, ": ").concat(_Utils.COLORS.FgGreen).concat(result.data.response.importSummaries ? result.data.response.importSummaries[0].href : (_result$data$response3 = result.data.response) === null || _result$data$response3 === void 0 ? void 0 : _result$data$response3.reference).concat(_Utils.ESCAPE, ".\nSummary:\n").concat((0, _Utils.prettyJson)(result.data))); - - if (callback) return callback((0, _languageCommon.composeNextState)(state, result.data)); - return (0, _languageCommon.composeNextState)(state, result.data); - }); - } - }); +function dv(dataElement, value) { + return { + dataElement, + value }; -} - +} @@ -1898,13 +821,13 @@

Source: Adaptor.js


diff --git a/docs/Client.js.html b/docs/Client.js.html new file mode 100644 index 0000000..1be6825 --- /dev/null +++ b/docs/Client.js.html @@ -0,0 +1,98 @@ + + + + + JSDoc: Source: Client.js + + + + + + + + + + +
+ +

Source: Client.js

+ + + + + + +
+
+
"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.request = request;
+
+var _axios = _interopRequireDefault(require("axios"));
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * The request client takes configuration from state and an axios request object
+ * then (1) logs the method and URL, (2) applies standard headers and auth
+ * before spreading the rest of the axios configuration, and (3) executes an
+ * axios request.
+ * @function
+ * @param {object} configuration - configuration must have a username and password
+ * @param {object} axiosRequest - the axiosRequest contains valid axios params: https://axios-http.com/docs/req_config
+ * @returns {Promise} a promise that will resolve to either a response object or an error object.
+ */
+function request({
+  username,
+  password
+}, axiosRequest) {
+  const {
+    method,
+    url,
+    params
+  } = axiosRequest;
+  console.log(`Sending ${method} request to ${url}`);
+  if (params) console.log(` with params:`, params); // NOTE: We don't follow redirects for unsafe methods: https://github.com/axios/axios/issues/2460
+
+  const safeRedirect = ['get', 'head', 'options', 'trace'].includes(method.toLowerCase());
+  return (0, _axios.default)({
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    responseType: 'json',
+    maxRedirects: safeRedirect ? 5 : 0,
+    auth: {
+      username,
+      password
+    },
+    // Note that providing headers or auth in the request object will overwrite.
+    ...axiosRequest
+  });
+}
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/global.html b/docs/global.html index 914ec79..932eb03 100644 --- a/docs/global.html +++ b/docs/global.html @@ -104,7 +104,7 @@

Methods

-

cancelEnrollment(enrollmentId, paramsopt, optionsopt, callbackopt) → {Operation}

+

request(configuration, axiosRequest) → {Promise}

@@ -112,8 +112,10 @@

cance
- Cancel a DHIS2 Enrollment -- To cancel an existing enrollment, you should supply the `enrollment identifier`(`enrollemt-id`) + The request client takes configuration from state and an axios request object +then (1) logs the method and URL, (2) applies standard headers and auth +before spreading the rest of the axios configuration, and (3) executes an +axios request.
@@ -137,8157 +139,6 @@

Parameters:
Type - Attributes - - - - - Description - - - - - - - - - enrollmentId - - - - - -string - - - - - - - - - - - - - - - - - - The `enrollment-id` of the enrollment you wish to cancel - - - - - - - params - - - - - -Object - - - - - - - - - <optional>
- - - - - - - - - - - Optional `import` parameters for `cancelEnrollment`. E.g. `{dryRun: true, IdScheme: 'CODE'}. Defaults to DHIS2 `default params` - - - - - - - options - - - - - -Object - - - - - - - - - <optional>
- - - - - - - - - - - Optional `flags` for the behavior of the `cancelEnrollment` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}` - - - - - - - callback - - - - - -function - - - - - - - - - <optional>
- - - - - - - - - - - Optional callback to handle the response - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

- Example `expression.js` of `cancelEnrollment`

- -
cancelEnrollments('PVqUD2hvU4E');
- - - - - - - - - -

completeEnrollment(enrollmentId, paramsopt, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Complete a DHIS2 Enrollment -- To complete an existing enrollment, you should supply the `enrollment identifier`(`enrollemt-id`) -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
enrollmentId - - -string - - - - - - - - - - The `enrollment-id` of the enrollment you wish to cancel
params - - -Object - - - - - - <optional>
- - - - - -
Optional `import` parameters for `completeEnrollment`. E.g. `{dryRun: true, IdScheme: 'CODE'}. Defaults to DHIS2 `default params`
options - - -Object - - - - - - <optional>
- - - - - -
Optional `flags` for the behavior of the `completeEnrollment` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}`
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

- Example `expression.js` of `completeEnrollment`

- -
completeEnrollment('PVqUD2hvU4E');
- - - - - - - - - -

create(resourceType, data, optionsopt, paramsopt, callbackopt) → {Operation}

- - - - - - -
- create data. A generic helper method to create a record of any kind in DHIS2 -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
resourceType - - -string - - - - - - - - - - Type of resource to create. E.g. `trackedEntityInstances`
data - - -Object - - - - - - - - - - Data that will be used to create a given instance of resource
options - - -Object - - - - - - <optional>
- - - - - -
Optional `options` to control the behavior of the `create` operation.` Defaults to `{operationName: 'create', apiVersion: null, responseType: 'json'}`
params - - -Object - - - - - - <optional>
- - - - - -
Optional `import parameters` for a given a resource. E.g. `{dryRun: true, importStrategy: CREATE}` See DHIS2 API documentation or discover. Defauls to `DHIS2 default params` for a given resource type.
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

- Example `expression.js` of `create`

- -
create('events', {
-  program: 'eBAyeGv0exc',
-  orgUnit: 'DiszpKrYNg8',
-  eventDate: date,
-  status: 'COMPLETED',
-  completedDate: date,
-  storedBy: 'admin',
-  coordinate: {
-    latitude: 59.8,
-    longitude: 10.9,
-  },
-  dataValues: [
-    {
-      dataElement: 'qrur9Dvnyt5',
-      value: '33',
-    },
-    {
-      dataElement: 'oZg33kd9taw',
-      value: 'Male',
-    },
-    {
-      dataElement: 'msodh3rEMJa',
-      value: date,
-    },
-  ],
-});
- - - - - - - - - -

createDataValues(data, optionsopt, paramsopt, callbackopt) → {Operation}

- - - - - - -
- Create DHIS2 Data Values -- This is used to send aggregated data to DHIS2 -- A data value set represents a set of data values which have a relationship, usually from being captured off the same data entry form. -- To send a set of related data values sharing the same period and organisation unit, we need to identify the period, the data set, the org unit (facility) and the data elements for which to report. -- You can also use this operation to send large bulks of data values which don't necessarily are logically related. -- To send data values that are not linked to a `dataSet`, you do not need to specify the dataSet and completeDate attributes. Instead, you will specify the period and orgUnit attributes on the individual data value elements instead of on the outer data value set element. This will enable us to send data values for various periods and organisation units -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
data - - -object - - - - - - - - - - The `data values` to upload or create. See example shape.
options - - -Object - - - - - - <optional>
- - - - - -
Optional `flags` for the behavior of the `createDataVaues` operation.
params - - -object - - - - - - <optional>
- - - - - -
Optional `import` parameters for `createDataValues`. E.g. `{dryRun: true, IdScheme: 'CODE'}. Defaults to DHIS2 `default params`. Run `discover` or visit DHIS2 Docs API to learn about available data values import parameters.
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

- Example `expression.js` of `createDataValues` for sending a set of related data values sharing the same period and organisation unit

- -
createDataValues({
-  dataSet: 'pBOMPrpg1QX',
-  completeDate: '2014-02-03',
-  period: '201401',
-  orgUnit: 'DiszpKrYNg8',
-  dataValues: [
-    {
-      dataElement: 'f7n9E0hX8qk',
-      value: '1',
-    },
-    {
-      dataElement: 'Ix2HsbDMLea',
-      value: '2',
-    },
-    {
-      dataElement: 'eY5ehpbEsB7',
-      value: '3',
-    },
-  ],
-});
- - - - - - - - - -

createEvents(data, paramsopt, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Create DHIS2 Events -- You will need a `program` which can be looked up using the `getPrograms` operation, an `orgUnit` which can be looked up using the `getMetadata` operation and passing `{organisationUnits: true}` as `resources` param, and a list of `valid data element identifiers` which can be looked up using the `getMetadata` passing `{dataElements: true}` as `resources` param. -- For events with registration, a `tracked entity instance identifier is required` -- For sending `events` to `programs with multiple stages`, you will need to also include the `programStage` identifier, the identifiers for `programStages` can be found in the `programStages` resource via a call to `getMetadata` operation. -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
data - - -Object - - - - - - - - - - The payload containing new values
params - - -Object - - - - - - <optional>
- - - - - -
Optional `import parameters` for events. E.g. `{dryRun: true, importStrategy: CREATE, filters:[]}` See DHIS2 Event Import parameters documentation or run `discover`. Defauls to `DHIS2 default import parameters`.
options - - -Object - - - - - - <optional>
- - - - - -
Optional `flags` for the behavior of the `createEvents` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}`
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - -
- state -
- - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

- Example `expression.js` of `createEvents` for a `single event` can look like this:

- -
createEvents({
-  program: 'eBAyeGv0exc',
-  orgUnit: 'DiszpKrYNg8',
-  eventDate: date,
-  status: 'COMPLETED',
-  completedDate: date,
-  storedBy: 'admin',
-  coordinate: {
-    latitude: 59.8,
-    longitude: 10.9,
-  },
-  dataValues: [
-    {
-      dataElement: 'qrur9Dvnyt5',
-      value: '33',
-    },
-    {
-      dataElement: 'oZg33kd9taw',
-      value: 'Male',
-    },
-    {
-      dataElement: 'msodh3rEMJa',
-      value: date,
-    },
-  ],
-});
- - - - - - - - - -

createPrograms(data, paramsopt, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Create a DHIS2 Tracker Program -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
data - - -Object - - - - - - - - - - The update data containing new values
params - - -Object - - - - - - <optional>
- - - - - -
Optional `import` parameters for `createPrograms`. E.g. `{dryRun: true, IdScheme: 'CODE'}. Defaults to DHIS2 `default params`
options - - -Object - - - - - - <optional>
- - - - - -
Optional `flags` for the behavior of the `getPrograms` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}`
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

- Example `expression.js` of `createPrograms` for a `single program` can look like this:

- -
createPrograms(state.data);
- - - - - - - - - -

createTEI(data, paramsopt, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Create Tracked Entity Instance. -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
data - - -Object - - - - - - - - - - The update data containing new values.
params - - -Object - - - - - - <optional>
- - - - - -
Optional `import parameters` for a given a resource. E.g. `{dryRun: true, importStrategy: CREATE}` See DHIS2 Import parameters documentation or run `discover`. Defauls to `DHIS2 default import parameters`.
options - - -Object - - - - - - <optional>
- - - - - -
`Optional` options for `createTEI` operation. Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}`.
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response.
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

- Example `expression.js` of `createTEI`.

- -
createTEI({
-   orgUnit: 'TSyzvBiovKh',
-   trackedEntityType: 'nEenWmSyUEp',
-   attributes: [
-      {
-         attribute: 'lZGmxYbs97q',
-         value: valUpsertTEI,
-      },
-      {
-         attribute: 'w75KJ2mc4zz',
-         value: 'Gigiwe',
-      },
-   ],
-   enrollments: [
-      {
-         orgUnit: 'TSyzvBiovKh',
-         program: 'fDd25txQckK',
-         programState: 'lST1OZ5BDJ2',
-         enrollmentDate: '2021-01-04',
-         incidentDate: '2021-01-04',
-      },
-   ],
-});
- - - - - - - - - -

del(resourceType, path, dataopt, paramsopt, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Delete a record. A generic helper function to delete an object -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
resourceType - - -string - - - - - - - - - - The type of resource to be deleted. E.g. `trackedEntityInstances`, `organisationUnits`, etc.
path - - -string - - - - - - - - - - Can be an `id` of an `object` or `path` to the `nested object` to `delete`.
data - - -Object - - - - - - <optional>
- - - - - -
Optional. This is useful when you want to remove multiple objects from a collection in one request. You can send `data` as, for example, `{"identifiableObjects": [{"id": "IDA"}, {"id": "IDB"}, {"id": "IDC"}]}`. See more on DHIS2 API docs
params - - -Object - - - - - - <optional>
- - - - - -
Optional `update` parameters e.g. `{preheatCache: true, strategy: 'UPDATE', mergeMode: 'REPLACE'}`. Run `discover` or see DHIS2 documentation
options - - -Object - - - - - - <optional>
- - - - - -
Optional `options` for `del` operation. Defaults to `{operationName: 'delete', apiVersion: state.configuration.apiVersion, responseType: 'json'}`
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

Example`deleting` a `tracked entity instance`

- -
del('trackedEntityInstances', 'LcRd6Nyaq7T');
- - - - - - - - - -

discover(httpMethod, endpoint) → {Operation}

- - - - - - -
- Discover `DHIS2` `api` `endpoint` `query parameters` and allowed `operators` for a given resource's endpoint. -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
httpMethod - - -string - - - - The HTTP to inspect parameter usage for a given endpoint, e.g., `get`, `post`,`put`,`patch`,`delete`
endpoint - - -string - - - - The path for a given endpoint. E.g. `/trackedEntityInstances` or `/dataValueSets`
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

Example getting a list of `parameters allowed` on a given `endpoint` for specific `http method`

- -
discover('post', '/trackedEntityInstances')
- - - - - - - - - -

enrollTEI(data, paramsopt, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Enroll a TEI into a program -- Enrolling a tracked entity instance into a program -- For enrolling `persons` into a `program`, you will need to first get the `identifier of the person` from the `trackedEntityInstances resource` via the `getTEIs` operation. -- Then, you will need to get the `program identifier` from the `programs` resource via the `getPrograms` operation. -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
data - - -Object - - - - - - - - - - The enrollment data. See example here
params - - -Object - - - - - - <optional>
- - - - - -
Optional `import` parameters for `createEnrollment`. E.g. `{dryRun: true, IdScheme: 'CODE'}. Defaults to DHIS2 `default params`
options - - -Object - - - - - - <optional>
- - - - - -
Optional `flags` for the behavior of the `enrollTEI` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}`
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

- Example `expression.js` of `createEnrollment` of a `person` into a `program` can look like this:

- -
enrollTEI({
-   trackedEntity: 'tracked-entity-id',
-   orgUnit: 'org-unit-id',
-   attributes: [
-   {
-      attribute: 'attribute-id',
-      value: 'attribute-value',
-   },
-   ],
-   enrollments: [
-   {
-      orgUnit: 'org-unit-id',
-      program: 'program-id',
-      enrollmentDate: '2013-09-17',
-      incidentDate: '2013-09-17',
-   },
-   ],
-});
- - - - - - - - - -

generateDhis2UID(optionsopt, callbackopt) → {Operation}

- - - - - - -
- Generate valid, random DHIS2 identifiers -- Useful for client generated Ids compatible with DHIS2 -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
options - - -Object - - - - - - <optional>
- - - - - -
Optional `options` for `generateDhis2UID` operation. Defaults to `{apiVersion: state.configuration.apiVersion,limit: 1,responseType: 'json'}`
callback - - -function - - - - - - <optional>
- - - - - -
Callback to handle response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

Example generating `three UIDs` from the DHIS2 server

- -
generateDhis2UID({limit: 3});
- - - - - - - - - -

getAnalytics(params, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Get analytical, aggregated data -- The analytics resource is powerful as it lets you query and retrieve data aggregated along all available data dimensions. -- For instance, you can ask the analytics resource to provide the aggregated data values for a set of data elements, periods and organisation units. -- Also, you can retrieve the aggregated data for a combination of any number of dimensions based on data elements and organisation unit group sets. -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
params - - -Object - - - - - - - - - - Analytics `query parameters`, e.g. `{dx: 'fbfJHSPpUQD;cYeuwXTCPkU',filters: ['pe:2014Q1;2014Q2','ou:O6uvpzGd5pu;lc3eMKXaEfw']}`. Run `discover` or visit DHIS2 API docs to get the params available.
options - - -Object - - - - - - <optional>
- - - - - -
`Optional` options for `getAnalytics` operation. Defaults to `{apiVersion: state.configuration.apiVersion, responseType: 'json'}`.
callback - - -function - - - - - - <optional>
- - - - - -
Callback to handle response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

Example getting only records where the data value is greater or equal to 6500 and less than 33000

- -
getAnalytics({
-  dimensions: [
-   'dx:fbfJHSPpUQD;cYeuwXTCPkU',
-   'pe:2014',
-   'ou:O6uvpzGd5pu;lc3eMKXaEfw',
-  ],
-  measureCriteria: 'GE:6500;LT:33000',
-});
- - - - - - - - - -

getData(resourceType, paramsopt, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Get data. Generic helper method for getting data of any kind from DHIS2. -- This can be used to get `DataValueSets`,`events`,`trackedEntityInstances`,`etc.` -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
resourceType - - -string - - - - - - - - - - The type of resource to get(use its `plural` name). E.g. `dataElements`, `trackedEntityInstances`,`organisationUnits`, etc.
params - - -Object - - - - - - <optional>
- - - - - -
Optional `query parameters` e.g. `{ou: 'DiszpKrYNg8'}`. Run `discover` or see DHIS2 docs for more details on which params to use for a given type of resource.
options - - -Object - - - - - - <optional>
- - - - - -
`Optional` options for `getData` operation. Defaults to `{operationName: 'getData', apiVersion: state.configuration.apiVersion, responseType: 'json'}`.
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - -
- state -
- - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

Example getting one `trackedEntityInstance` with `Id` 'dNpxRu1mWG5' for a given `orgUnit(DiszpKrYNg8)`

- -
getData('trackedEntityInstances', {
-   fields: '*',
-   ou: 'DiszpKrYNg8',
-   entityType: 'nEenWmSyUEp',
-   trackedEntityInstance: 'dNpxRu1mWG5',
-});
- - - - - - - - - -

getDataValues(params, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Get DHIS2 Data Values. -- This operation retrives data values from DHIS2 Web API by interacting with the `dataValueSets` resource -- Data values can be retrieved in XML, JSON and CSV format. -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
params - - -Object - - - - - - - - - - `Query` parameters for `getDataValues`. E.g. `{dataset: 'pBOMPrpg1QX', limit: 3, period: 2021, orgUnit: 'DiszpKrYNg8'} Run `discover` or see DHIS2 API docs for available `Data Value Set Query Parameters`.
options - - -Object - - - - - - <optional>
- - - - - -
Optional `options` for `getDataValues` operation. Defaults to `{apiVersion: state.configuration.apiVersion, responseType: 'json'}`
callback - - -function - - - - - - <optional>
- - - - - -
Optional `callback` to handle the response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

- Example getting **two** `data values` associated with a specific `orgUnit`, `dataSet`, and `period `

- -
getDataValues({
-  orgUnit: 'DiszpKrYNg8',
-  period: '202010',
-  dataSet: 'pBOMPrpg1QX',
-  limit: 2,
-});
- - - - - - - - - -

getEnrollments(params, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Get DHIS2 Enrollments -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
params - - -Object - - - - - - - - - - `Query` parameters for `getEnrollments`. See here
options - - -Object - - - - - - <optional>
- - - - - -
Optional `flags` for the behavior of the `getEnrollments` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}`
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

- To constrain the response to `enrollments` which are part of a `specific program` you can include a `program query parameter`

- -
getEnrollments({
-  ou: 'O6uvpzGd5pu',
-  ouMode: 'DESCENDANTS',
-  program: 'ur1Edk5Oe2n',
-  fields: '*',
-});
- - - - - - - - - -

getEvents(params, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Get annonymous events or tracker events. -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
params - - -Object - - - - - - - - - - `import` parameters for `getEvents`. See examples here
options - - -Object - - - - - - <optional>
- - - - - -
`Optional` options for `getEvents` operation. Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}`.
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response.
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

- Query for `all events` with `children` of a certain `organisation unit`

- -
getEvents({ orgUnit: 'YuQRtpLP10I', ouMode: 'CHILDREN' });
- - - - - - - - - -

getMetadata(resources, paramsopt, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Get metadata. A generic helper function to get metadata records from a given DHIS2 instance -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
resources - - -Array.<string> - - - - - - - - - - Required. List of metadata resources to fetch. E.g. `['organisationUnits', 'attributes']` or like `'dataSets'` if you only want a single type of resource. See `getResources` to see the types of resources available.
params - - -Object - - - - - - <optional>
- - - - - -
Optional `query parameters` e.g. `{filters: ['name:like:ANC'],fields:'*'}`. See `discover` or visit DHIS2 API docs
options - - -Object - - - - - - <optional>
- - - - - -
Optional `options` for `getMetadata` operation. Defaults to `{operationName: 'getMetadata', apiVersion: state.configuration.apiVersion, responseType: 'json'}`
callback - - -function - - - - - - <optional>
- - - - - -
Optional `callback` to handle the response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

Example getting a list of `data elements` and `indicators` where `name` includes the word **ANC**

- -
getMetadata(['dataElements', 'indicators'], {
-     filters: ['name:like:ANC'],
-});
- - - - - - - - - -

getPrograms(params, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Get DHIS2 Tracker Programs. -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
params - - -Object - - - - - - - - - - `import` parameters for `getPrograms`. See DHIS2 api documentation for allowed query parameters
options - - -Object - - - - - - <optional>
- - - - - -
Optional `flags` for the behavior of the `getPrograms` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}`
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

- Query for `all programs` with a certain `organisation unit`

- -
getPrograms({ orgUnit: 'DiszpKrYNg8' , fields: '*' });
- - - - - - - - - -

getRelationships(params, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Get DHIS2 Relationships(links) between two entities in tracker. These entities can be tracked entity instances, enrollments and events. -- All the tracker operations, `getTEIs`, `getEnrollments` and `getEvents` also list their relationships if requested in the `field` filter. -- To list all relationships, this requires you to provide the UID of the trackedEntityInstance, Enrollment or event that you want to list all the relationships for. -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
params - - -Object - - - - - - - - - - `Query` parameters for `getRelationships`. See examples here
options - - -Object - - - - - - <optional>
- - - - - -
Optional `flags` for the behavior of the `getRelationships` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}`
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

- A query for `all relationships` associated with a `specific tracked entity instance` can look like this:

- -
getRelationships({ tei: 'F8yKM85NbxW', fields: '*' });
- - - - - - - - - -

getResources(paramsopt, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Get DHIS2 api resources -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
params - - -Object - - - - - - <optional>
- - - - - -
The `optional` query parameters for this endpoint. E.g `{filter: 'singular:like:attribute'}`.
options - - -Object - - - - - - <optional>
- - - - - -
The `optional` options, specifiying the filter expression. E.g. `singular:eq:attribute`.
callback - - -function - - - - - - <optional>
- - - - - -
The `optional callback function that will be called to handle data returned by this function.
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

Example getting a resource named `attribute`, in `xml` format, returning all the fields

- -
getResources('dataElement', {
-     filter: 'singular:eq:attribute',
-     fields: '*',
-     responseType: 'xml',
-});
- - - - - - - - - -

getSchema(resourceType, params, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Get schema of a given resource type, in any data format supported by DHIS2 -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
resourceType - - -string - - - - - - - - - - The type of resource to be updated(`singular` version of the `resource name`). E.g. `dataElement`, `organisationUnit`, etc. Run `getResources` to see available resources and their corresponding `singular` names.
params - - -Object - - - - - - - - - - Optional `query parameters` for the `getSchema` operation. e.g. `{ fields: 'properties' ,skipPaging: true}`. Run`discover` or See DHIS2 API Docs
options - - -Object - - - - - - <optional>
- - - - - -
Optional options for `getSchema` method. Defaults to `{apiVersion: state.configuration.apiVersion, responseType: 'json'}`
callback - - -function - - - - - - <optional>
- - - - - -
Optional `callback` to handle the response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

Example getting the `schema` for `dataElement` in XML

- -
getSchema('dataElement', '{ fields: '*' }, { responseType: 'xml' });
- - - - - - - - - -

getTEIs(paramsopt, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Get Tracked Entity Instance(s). -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
params - - -Object - - - - - - <optional>
- - - - - -
Optional `query parameters` e.g. `{ou: 'DiszpKrYNg8', filters: ['lZGmxYbs97q':GT:5']}`. Run `discover` or see DHIS2 docs for more details on which params to use when querying tracked entities instances.
options - - -Object - - - - - - <optional>
- - - - - -
`Optional` options for `getTEIs` operation. Defaults to `{apiVersion: state.configuration.apiVersion, responseType: 'json'}`.
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response.
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

- Example `getTEIs` `expression.js` for fetching a `single` `Tracked Entity Instance` with all the fields included.

- -
getTEIs({
-  fields: '*',
-  ou: 'CMqUILyVnBL',
-  trackedEntityInstance: 'HNTA9qD6EEG',
-  skipPaging: true,
-});
- - - - - - - - - -

patch(resourceType, path, data, paramsopt, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Patch a record. A generic helper function to send partial updates on one or more object properties. -- You are not required to send the full body of object properties. -- This is useful for cases where you don't want or need to update all properties on a object. -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
resourceType - - -string - - - - - - - - - - The type of resource to be updated. E.g. `dataElements`, `organisationUnits`, etc.
path - - -string - - - - - - - - - - The `id` or `path` to the `object` to be updated. E.g. `FTRrcoaog83` or `FTRrcoaog83/{collection-name}/{object-id}`
data - - -Object - - - - - - - - - - Data to update. Include only the fields you want to update. E.g. `{name: "New Name"}`
params - - -Object - - - - - - <optional>
- - - - - -
Optional `update` parameters e.g. `{preheatCache: true, strategy: 'UPDATE', mergeMode: 'REPLACE'}`. Run `discover` or see DHIS2 documentation
options - - -Object - - - - - - <optional>
- - - - - -
Optional options for update method. Defaults to `{operationName: 'patch', apiVersion: state.configuration.apiVersion, responseType: 'json'}`
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

Example `patching` a `data element`

- -
patch('dataElements', 'FTRrcoaog83',
-{
-  name: 'New Name',
-});
- - - - - - - - - -

update(resourceType, path, data, paramsopt, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Update data. A generic helper function to update a resource object of any type. -- It requires to send `all required fields` or the `full body` -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
resourceType - - -string - - - - - - - - - - The type of resource to be updated. E.g. `dataElements`, `organisationUnits`, etc.
path - - -string - - - - - - - - - - The `id` or `path` to the `object` to be updated. E.g. `FTRrcoaog83` or `FTRrcoaog83/{collection-name}/{object-id}`
data - - -Object - - - - - - - - - - Data to update. It requires to send `all required fields` or the `full body`. If you want `partial updates`, use `patch` operation.
params - - -Object - - - - - - <optional>
- - - - - -
Optional `update` parameters e.g. `{preheatCache: true, strategy: 'UPDATE', mergeMode: 'REPLACE'}`. Run `discover` or see DHIS2 documentation
options - - -Object - - - - - - <optional>
- - - - - -
Optional options for update method. Defaults to `{operationName: 'update', apiVersion: state.configuration.apiVersion, responseType: 'json'}`
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

Example `updating` a `data element`

- -
update('dataElements', 'FTRrcoaog83',
-{
-  displayName: 'New display name',
-  aggregationType: 'SUM',
-  domainType: 'AGGREGATE',
-  valueType: 'NUMBER',
-  name: 'Accute Flaccid Paralysis (Deaths < 5 yrs)',
-  shortName: 'Accute Flaccid Paral (Deaths < 5 yrs)',
-});
- - - - - - - - - -

updateEnrollments(path, data, paramsopt, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Update a DHIS2 Enrollemts -- To update an existing enrollment, the format of the payload is the same as that of `creating an event` via `createEvents` operations -- But you should supply the `identifier` of the object you are updating -- The payload has to contain `all`, even `non-modified`, `attributes`. -- Attributes that were present before and are not present in the current payload any more will be removed by DHIS2. -- If you do not want this behavior, please use `upsert` operation to upsert your events. -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
path - - -string - - - - - - - - - - Path to the object being updated. This can be an `id` or path to an `object` in a `nested collection` on the object(E.g. `/api/{collection-object}/{collection-object-id}/{collection-name}/{object-id}`)
data - - -Object - - - - - - - - - - The update data containing new values
params - - -Object - - - - - - <optional>
- - - - - -
Optional `import` parameters for `updateEnrollments`. E.g. `{dryRun: true, IdScheme: 'CODE'}. Defaults to DHIS2 `default params`
options - - -Object - - - - - - <optional>
- - - - - -
Optional `flags` for the behavior of the `updateEnrollments` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}`
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

- Example `expression.js` of `updateEnromments`

- -
updateEnrollments('PVqUD2hvU4E', state.data);
- - - - - - - - - -

updateEvents(path, data, paramsopt, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Update DHIS2 Event. -- To update an existing event, the format of the payload is the same as that of `creating an event` via `createEvents` operations -- But you should supply the `identifier` of the object you are updating -- The payload has to contain `all`, even `non-modified`, `attributes`. -- Attributes that were present before and are not present in the current payload any more will be removed by DHIS2. -- If you do not want this behavior, please use `upsert` operation to upsert your events. -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
path - - -string - - - - - - - - - - Path to the object being updated. This can be an `id` or path to an `object` in a `nested collection` on the object(E.g. `/api/{collection-object}/{collection-object-id}/{collection-name}/{object-id}`)
data - - -Object - - - - - - - - - - The update data containing new values
params - - -Object - - - - - - <optional>
- - - - - -
Optional `import` parameters for `updateEvents`. E.g. `{dryRun: true, IdScheme: 'CODE'}. Defaults to DHIS2 `default params`
options - - -Object - - - - - - <optional>
- - - - - -
Optional `flags` for the behavior of the `updateEvents` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}`
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

- Example `expression.js` of `updateEvents`

- -
updateEvents('PVqUD2hvU4E', { events: [
- {
-   program: 'eBAyeGv0exc',
-   orgUnit: 'DiszpKrYNg8',
-   eventDate: date,
-   status: 'COMPLETED',
-   storedBy: 'admin',
-   coordinate: {
-     latitude: '59.8',
-     longitude: '10.9',
-   },
-   dataValues: [
-     {
-       dataElement: 'qrur9Dvnyt5',
-       value: '22',
-     },
-     {
-       dataElement: 'oZg33kd9taw',
-       value: 'Male',
-     },
-   ],
- }]
-});
- - - - - - - - - -

updatePrograms(path, data, paramsopt, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Update DHIS2 Tracker Programs -- To update an existing program, the format of the payload is the same as that of `creating an event` via `createEvents` operations -- But you should supply the `identifier` of the object you are updating -- The payload has to contain `all`, even `non-modified`, `attributes`. -- Attributes that were present before and are not present in the current payload any more will be removed by DHIS2. -- If you do not want this behavior, please use `upsert` operation to upsert your events. -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
path - - -string - - - - - - - - - - Path to the object being updated. This can be an `id` or path to an `object` in a `nested collection` on the object(E.g. `/api/{collection-object}/{collection-object-id}/{collection-name}/{object-id}`)
data - - -Object - - - - - - - - - - The update data containing new values
params - - -Object - - - - - - <optional>
- - - - - -
Optional `import` parameters for `updatePrograms`. E.g. `{dryRun: true, IdScheme: 'CODE'}. Defaults to DHIS2 `default params`
options - - -Object - - - - - - <optional>
- - - - - -
Optional `flags` for the behavior of the `getPrograms` operation.Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}`
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

- Example `expression.js` of `updatePrograms`

- -
updatePrograms('PVqUD2hvU4E', state.data);
- - - - - - - - - -

updateTEI(path, data, paramsopt, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Update a Tracked Entity Instance. -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
path - - -string - - - - - - - - - - Path to the object being updated. This can be an `id` or path to an `object` in a `nested collection` on the object(E.g. `/api/{collection-object}/{collection-object-id}/{collection-name}/{object-id}`).
data - - -Object - - - - - - - - - - The update data containing new values.
params - - -Object - - - - - - <optional>
- - - - - -
Optional `import parameters` for a given a resource. E.g. `{dryRun: true, importStrategy: CREATE, filters:[]}` See DHIS2 Import parameters documentation or run `discover`. Defauls to `DHIS2 default import parameters`.
options - - -Object - - - - - - <optional>
- - - - - -
`Optional` options for `updateTEI` operation. Defaults to `{apiVersion: state.configuration.apiVersion,responseType: 'json'}`.
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response.
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

- Example `expression.js` of `updateTEI`.

- -
updateTEI('PVqUD2hvU4E', {
-   orgUnit: 'TSyzvBiovKh',
-   trackedEntityType: 'nEenWmSyUEp',
-   attributes: [
-      {
-         attribute: 'lZGmxYbs97q',
-         value: valUpsertTEI,
-      },
-      {
-         attribute: 'w75KJ2mc4zz',
-         value: 'Gigiwe',
-      },
-   ],
-   enrollments: [
-      {
-         orgUnit: 'TSyzvBiovKh',
-         program: 'fDd25txQckK',
-         programState: 'lST1OZ5BDJ2',
-         enrollmentDate: '2021-01-04',
-         incidentDate: '2021-01-04',
-      },
-   ],
-});
- - - - - - - - - -

upsert(resourceType, uniqueAttribute, data, paramsopt, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Upsert a record. A generic helper function used to atomically either insert a row, or on the basis of the row already existing, UPDATE that existing row instead. -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeAttributesDescription
resourceType - - -string - - - - - - - - - - The type of a resource to `insert` or `update`. E.g. `trackedEntityInstances`
uniqueAttribute - - -Object - - - - - - - - - - An object containing a `attributeId` and `attributeValue` which will be used to uniquely identify the record
data - - -Object - - - - - - - - - - The update data containing new values
params - - -Object - - - - - - <optional>
- - - - - -
Optional `import` parameters e.g. `{ou: 'lZGmxYbs97q', filters: ['w75KJ2mc4zz:EQ:Jane']}`
options - - -Object - - - - - - <optional>
- - - - - -
`Optional` options for `upsertTEI` operation. Defaults to `{replace: false, apiVersion: state.configuration.apiVersion,strict: true,responseType: 'json'}`.
callback - - -function - - - - - - <optional>
- - - - - -
Optional callback to handle the response
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
To Do:
-
- -
- -
- - - - - - - - - - - - - -
Throws:
- - - -
-
-
- - Throws range error -
-
-
-
-
-
- Type -
-
- -RangeError - - -
-
-
-
-
- - - - - -
Returns:
- - - - -
-
- Type -
-
- -Operation - - -
-
- - - - - - -
Example
- -

- Example `expression.js` of upsert

- -
upsert(
-   'trackedEntityInstances',
-   {
-      attributeId: 'lZGmxYbs97q',
-         attributeValue: state =>
-            state.data.attributes.find(obj => obj.attribute === 'lZGmxYbs97q')
-            .value,
-   },
-   state.data,
-   { ou: 'TSyzvBiovKh' }
-);
- - - - - - - - - -

upsertTEI(uniqueAttributeId, data, optionsopt, callbackopt) → {Operation}

- - - - - - -
- Update TEI if exists otherwise create. -- Update if the record exists otherwise insert a new record. -- This is useful for idempotency and duplicate record management. -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - @@ -8300,128 +151,46 @@
Parameters:
- - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - + - + - - - + @@ -8462,7 +231,7 @@
Parameters:
Source:
@@ -8485,40 +254,15 @@
Parameters:
-
Throws:
- - - -
-
-
- - Throws `RangeError` when `uniqueAttributeId` is `invalid` or `not unique`. -
-
-
-
-
-
- Type -
-
- -RangeError - - -
-
-
-
-
- - -
Returns:
+
+ a promise that will resolve to either a response object or an error object. +
+
@@ -8527,7 +271,7 @@
Returns:
-Operation +Promise
@@ -8538,30 +282,6 @@
Returns:
-
Example
- -

- Example `expression.js` for upserting a tracked entity instance on attribute with Id `lZGmxYbs97q`.

- -
upsertTEI('lZGmxYbs97q', {
-  orgUnit: 'TSyzvBiovKh',
-  trackedEntityType: 'nEenWmSyUEp',
-  attributes: [
-    {
-      attribute: 'lZGmxYbs97q',
-      value: '77790012',
-    },
-    {
-      attribute: 'w75KJ2mc4zz',
-      value: 'Gigiwe',
-    },
-    {
-      attribute: 'zDhUuAYrxNC',
-      value: 'Mwanza',
-    },
-  ],
-});
- - @@ -8579,13 +299,13 @@
Example

diff --git a/docs/index.html b/docs/index.html index 13b5dca..47bd717 100644 --- a/docs/index.html +++ b/docs/index.html @@ -44,144 +44,92 @@

Language DHIS2 Build Status

-

Language Pack for building expressions and operations for working with -the DHIS2 API.

+

Language Pack for building expressions and operations for working with the +DHIS2 API.

Documentation

View the docs site for full -technical documentation. Below, find a samples of the most commonly used helper -functions.

+technical documentation and lots of examples for how to use the various +helper functions.

Sample State

{
   "configuration": {
     "username": "admin",
     "password": "district",
-    "hostUrl": "https://play.dhis2.org/2.35.1"
+    "hostUrl": "https://play.dhis2.org/2.36.6"
   },
-  "data": {
-    "a": 1,
-    "b": 2
-  }
+  "data": { "a": 1, "b": 2 }
 }
 
-

Analytics API

-

Fetch analytics data for PMTCT data over last 6 months.

-
fetchAnalytics({
-  query: {
-    dimension: ['dx:CYI5LEmm3cG;GDVU1o5rTNF', 'pe:LAST_6_MONTHS'],
-    filter: 'ou:GHlyx9Pg9mn',
-    displayProperty: 'NAME',
-    outputIdScheme: 'UID',
-  },
-});
-
-

Tracked Entity API

-

Create a new tracked entity instance and enroll them from a CommCare form submission.

-
createTEI({
-  trackedEntityType: 'nEenWmSyUEp',
-  orgUnit: 'g8upMTyEZGZ',
-  attributes: [
-    {
-      attribute: 'w75KJ2mc4zz',
-      value: dataValue('form.first_name')(state),
-    },
-    {
-      attribute: 'zDhUuAYrxNC',
-      value: dataValue('form.last_name')(state),
-    },
-  ],
-  enrollments: [
-    {
-      orgUnit: 'g8upMTyEZGZ',
-      program: 'IpHINAT79UW',
-      enrollmentDate: '2019-04-08',
-      incidentDate: '2019-04-08',
+

Development

+

Clone the repo and run npm install.

+

Run tests using npm run test or npm run test:watch. (NB: that this repo also +contain integration tests which can be run with npm run integration-test.)

+

Make your changes to the files in src/ and then use npm run build to +generate output files in lib/.

+

Unit Tests

+

Unit tests allows to test the functionalities of the adaptor helper functions +such as:

+
+

Does create('events', payload) perform a post request to the correct DHIS2 +API?

+
+

To run unit tests execute npm run test (they're the default tests).

+

Anytime a new functionality is added to the helper functions, more unit tests +needs to be added.

+

End-to-end integration tests

+

Integration tests allow us to test the end-to-end behavior of the helper +functions and also to test the examples we provide via inline documentation.

+

For example with integration tests we answer the following question:

+
+

Does create('events', eventPayload) actually create a new event in a live +DHIS2 system?

+
+

To run integration tests, execute npm run integration-test. These tests use +network I/O and a public connection to a DHIS2 "play" server so their timing and +performance is unpredictable. Consider adding an increased timeout, and +modifying the orgUnit, program, etc., IDs set in globalState.

+

Troubleshooting the tests

+
    +
  • +

    Depending on your internet strength please consider changing the global +timeout in the test/mocha.opts file to avoid faillures related to network +timeouts.

    +
  • +
  • +

    The behavior of the tests in test/integration.js is very unpredictable; they +depend on the configuration of a target DHIS2 instance. Currently you need +to have at least one organisation unit with one program, one +trackedEntityInstance and one programStage in it. These components need to be +well configured for the integration tests to work. For example: the +trackedEntityInstance need to be enrolled to the program, which should be +created in that organisation unit and contains at least that programStage. If +the tests fail, you must adjust these attributes in the +before hook:

    +
  • +
+
before(done => {
+  fixture.initialState = {
+    configuration: {
+      username: 'admin',
+      password: 'district',
+      hostUrl: 'https://play.dhis2.org/2.36.6',
     },
-  ],
-});
-
-

Upsert a tracked entity instance from a CommCare form submission.

-
upsertTEI(
-  'w75KJ2mc4zz', // match on 'patientID', a custom external ID in dhis2
-  {
-    trackedEntityType: 'nEenWmSyUEp',
-    orgUnit: 'g8upMTyEZGZ',
-    attributes: [
-      {
-        attribute: 'w75KJ2mc4zz',
-        value: dataValue('form.first_name')(state),
-      },
-      {
-        attribute: 'zDhUuAYrxNC',
-        value: dataValue('form.last_name')(state),
-      },
-    ],
-  }
-);
-
-

Events API

-

Events API expression

-
event(
-  fields(
-    field("program", "eBAyeGv0exc"),
-    field("orgUnit", "DiszpKrYNg8"),
-    field("eventDate", dataValue("date")),
-    field("status", "COMPLETED"),
-    field("storedBy", "admin"),
-    field("coordinate", {
-      "latitude": "59.8",
-      "longitude": "10.9"
-    }),
-    field("dataValues", function(state) {
-      return [
-        dataElement("qrur9Dvnyt5", dataValue("prop_a"))(state)
-        dataElement("oZg33kd9taw", dataValue("prop_b"))(state)
-        dataElement("msodh3rEMJa", dataValue("prop_c"))(state)
-      ]
-    })
-  )
-)
-
-

Current fetchEvents API expression (Optional postUrl for a complete fetch)

-
fetchEvents({
-  fields: {
+    program: 'IpHINAT79UW',
     orgUnit: 'DiszpKrYNg8',
-    program: 'eBAyeGv0exc',
-    endDate: '2016-01-01',
-  },
-  postUrl: 'https://www.openfn.org/inbox/123',
+    trackedEntityInstance: 'uhubxsfLanV',
+    programStage: 'eaDHS084uMp',
+  };
+  done();
 });
 
-

Reference on how to query and read events https://docs.dhis2.org/2.22/en/developer/html/ch01s15.html#d5e1994

-

Data Values / Data Value Sets API

-

Current DataValueSets API expression

-
dataValueSet({
-  dataSet: dataValue('set'),
-  orgUnit: 'DiszpKrYNg8',
-  period: '201402',
-  completeData: '2014-03-03',
-  dataValues: [
-    dataElement('f7n9E0hX8qk', dataValue('data[0].site_school_number')),
-    dataElement('Ix2HsbDMLea', dataValue('age')),
-    dataElement('eY5ehpbEsB7', 30),
-  ],
-});
-
-

Current fetchData API expression (Optional postUrl for a complete fetch)

-
fetchData({
-  fields: {
-    dataSet: 'pBOMPrpg1QX',
-    orgUnit: 'DiszpKrYNg8',
-    period: '201711',
-  },
-  postUrl: 'https://www.openfn.org/inbox/123',
-});
-
-

Reference on how to read data values https://docs.dhis2.org/2.22/en/developer/html/ch01s13.html#d5e1642

-

Docs

-

Development

-

Clone the repo, run npm install.

-

Run tests using npm run test or npm run test:watch

-

Build the project using make.

+
    +
  • Make sure the update and upsert integration tests don't affect those +initial organisation units, programs, programStage and trackedEntityInstance +required. Otherwise the create integration tests would be broken again; and +that's an endless faillure loop :(
  • +
+

Anytime a new example is added in the documentation of a helper function, a new +integration test should be built.

@@ -192,13 +140,13 @@

Development


- Documentation generated by JSDoc 3.6.6 on Tue Mar 09 2021 16:30:47 GMT+0000 (Greenwich Mean Time) + Documentation generated by JSDoc 3.6.6 on Thu Dec 23 2021 06:44:11 GMT-0700 (Mountain Standard Time)
diff --git a/docs/module-Adaptor-configMigrationHelper.html b/docs/module-Adaptor-configMigrationHelper.html new file mode 100644 index 0000000..7337390 --- /dev/null +++ b/docs/module-Adaptor-configMigrationHelper.html @@ -0,0 +1,244 @@ + + + + + JSDoc: Class: configMigrationHelper + + + + + + + + + + +
+ +

Class: configMigrationHelper

+ + + + + + +
+ +
+ +

+ Adaptor~configMigrationHelper(state) → {object}

+ + +
+ +
+
+ + + + + + +

new configMigrationHelper(state) → {object}

+ + + + + + +
+ Migrates `apiUrl` to `hostUrl` if `hostUrl` is `blank`. +For `OpenFn.org` users with the `old-style configuration`. +
+ + + + + + + + + +
Parameters:
+ + +
NameTypeAttributes
uniqueAttributeId - - -string - - - - - - - - - - Tracked Entity Instance unique identifier attribute used during matching.
dataconfiguration -Object - - - - - - - - - - Payload data for new tracked entity instance or updated data for an existing tracked entity instance.
options - - -Object +object - - <optional>
- - - - - -
`Optional` options for `upsertTEI` operation. Defaults to `{apiVersion: state.configuration.apiVersion,strict: true,responseType: 'json'}`.configuration must have a username and password
callbackaxiosRequest -function +object - - <optional>
- - - - - -
Optional `callback` to handle the response.the axiosRequest contains valid axios params: https://axios-http.com/docs/req_config
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
state + + +object + + + + the runtime state
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +object + + +
+
+ + + + + + +
Example
+ +
configMigrationHelper(state)
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-Adaptor-execute.html b/docs/module-Adaptor-execute.html new file mode 100644 index 0000000..76862e0 --- /dev/null +++ b/docs/module-Adaptor-execute.html @@ -0,0 +1,259 @@ + + + + + JSDoc: Class: execute + + + + + + + + + + +
+ +

Class: execute

+ + + + + + +
+ +
+ +

+ Adaptor~execute(…operations) → {Operation}

+ + +
+ +
+
+ + + + + + +

new execute(…operations) → {Operation}

+ + + + + + +
+ Execute a sequence of operations. +Wraps `language-common/execute`, and prepends initial state for DHIS2. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
operations + + +Operations + + + + + + + + + + <repeatable>
+ +
Operations to be performed.
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Operation + + +
+
+ + + + + + +
Example
+ +
execute(
+  create('foo'),
+  delete('bar')
+)(state)
+ + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/module-Adaptor.html b/docs/module-Adaptor.html new file mode 100644 index 0000000..e17aaea --- /dev/null +++ b/docs/module-Adaptor.html @@ -0,0 +1,2658 @@ + + + + + JSDoc: Module: Adaptor + + + + + + + + + + +
+ +

Module: Adaptor

+ + + + + + +
+ +
+ + + +
+ +
+
+ + + + + +
+ + + + + + +

Classes

+ +
+
configMigrationHelper
+
+ +
execute
+
+
+ + + + + + + + + + + +

Methods

+ + + + + + + +

(inner) attr(attribute, value) → {object}

+ + + + + + +
+ Converts an attribute ID and value into a DSHI2 attribute object +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
attribute + + +string + + + + A tracked entity instance (TEI) attribute ID.
value + + +string + + + + The value for that attribute.
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +object + + +
+
+ + + + + + +
Example
+ +
attr('w75KJ2mc4zz', 'Elias')
+ + + + + + + + + +

(inner) create(resourceType, data, optionsopt, callbackopt) → {Operation}

+ + + + + + +
+ Create a record +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
resourceType + + +string + + + + + + + + + + + + Type of resource to create. E.g. `trackedEntityInstances`, `programs`, `events`, ...
data + + +Object + + + + + + + + + + + + Data that will be used to create a given instance of resource. To create a single instance of a resource, `data` must be a javascript object, and to create multiple instances of a resources, `data` must be an array of javascript objects.
options + + +Object + + + + + + <optional>
+ + + + + +
+ + Optional `options` to define URL parameters via params (E.g. `filter`, `dimension` and other import parameters), request config (E.g. `auth`) and the DHIS2 apiVersion.
callback + + +function + + + + + + <optional>
+ + + + + +
+ + false + + Optional callback to handle the response
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Operation + + +
+
+ + + + + + +
Examples
+ +

a program

+ +
create('programs', {
+  name: 'name 20',
+  shortName: 'n20',
+  programType: 'WITHOUT_REGISTRATION',
+});
+ +

an event

+ +
create('events', {
+  program: 'eBAyeGv0exc',
+  orgUnit: 'DiszpKrYNg8',
+  status: 'COMPLETED',
+});
+ +

a trackedEntityInstance

+ +
create('trackedEntityInstances', {
+  orgUnit: 'TSyzvBiovKh',
+  trackedEntityType: 'nEenWmSyUEp',
+  attributes: [
+    {
+      attribute: 'w75KJ2mc4zz',
+      value: 'Gigiwe',
+    },
+  ]
+});
+ +

a dataSet

+ +
create('dataSets', { name: 'OpenFn Data Set', periodType: 'Monthly' });
+ +

a dataSetNotification

+ +
create('dataSetNotificationTemplates', {
+  dataSetNotificationTrigger: 'DATA_SET_COMPLETION',
+  notificationRecipient: 'ORGANISATION_UNIT_CONTACT',
+  name: 'Notification',
+  messageTemplate: 'Hello',
+  deliveryChannels: ['SMS'],
+  dataSets: [],
+});
+ +

a dataElement

+ +
create('dataElements', {
+  aggregationType: 'SUM',
+  domainType: 'AGGREGATE',
+  valueType: 'NUMBER',
+  name: 'Paracetamol',
+  shortName: 'Para',
+});
+ +

a dataElementGroup

+ +
create('dataElementGroups', {
+  name: 'Data Element Group 1',
+  dataElements: [],
+});
+ +

a dataElementGroupSet

+ +
create('dataElementGroupSets', {
+  name: 'Data Element Group Set 4',
+  dataDimension: true,
+  shortName: 'DEGS4',
+  dataElementGroups: [],
+});
+ +

a dataValueSet

+ +
create('dataValueSets', {
+  dataElement: 'f7n9E0hX8qk',
+  period: '201401',
+  orgUnit: 'DiszpKrYNg8',
+  value: '12',
+});
+ +

a dataValueSet with related dataValues

+ +
create('dataValueSets', {
+  dataSet: 'pBOMPrpg1QX',
+  completeDate: '2014-02-03',
+  period: '201401',
+  orgUnit: 'DiszpKrYNg8',
+  dataValues: [
+    {
+      dataElement: 'f7n9E0hX8qk',
+      value: '1',
+    },
+    {
+      dataElement: 'Ix2HsbDMLea',
+      value: '2',
+    },
+    {
+      dataElement: 'eY5ehpbEsB7',
+      value: '3',
+    },
+  ],
+});
+ +

an enrollment

+ +
create('enrollments', {
+  trackedEntityInstance: 'bmshzEacgxa',
+  orgUnit: 'TSyzvBiovKh',
+  program: 'gZBxv9Ujxg0',
+  enrollmentDate: '2013-09-17',
+  incidentDate: '2013-09-17',
+});
+ + + + + + + + + +

(inner) destroy(resourceType, path, dataopt, optionsopt, callbackopt) → {Operation}

+ + + + + + +
+ Delete a record. A generic helper function to delete an object +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
resourceType + + +string + + + + + + + + + + + + The type of resource to be deleted. E.g. `trackedEntityInstances`, `organisationUnits`, etc.
path + + +string + + + + + + + + + + + + Can be an `id` of an `object` or `path` to the `nested object` to `delete`.
data + + +Object + + + + + + <optional>
+ + + + + +
+ + null + + Optional. This is useful when you want to remove multiple objects from a collection in one request. You can send `data` as, for example, `{"identifiableObjects": [{"id": "IDA"}, {"id": "IDB"}, {"id": "IDC"}]}`. See more on DHIS2 API docs
options + + +Object + + + + + + <optional>
+ + + + + +
+ + Optional `options` for `del` operation including params e.g. `{preheatCache: true, strategy: 'UPDATE', mergeMode: 'REPLACE'}`. Run `discover` or see DHIS2 documentation. Defaults to `{operationName: 'delete', apiVersion: state.configuration.apiVersion, responseType: 'json'}`
callback + + +function + + + + + + <optional>
+ + + + + +
+ + false + + Optional callback to handle the response
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Operation + + +
+
+ + + + + + +
Example
+ +

a tracked entity instance

+ +
destroy('trackedEntityInstances', 'LcRd6Nyaq7T');
+ + + + + + + + + +

(inner) discover(httpMethod, endpoint) → {Operation}

+ + + + + + +
+ Discover `DHIS2` `api` `endpoint` `query parameters` and allowed `operators` for a given resource's endpoint. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
httpMethod + + +string + + + + The HTTP to inspect parameter usage for a given endpoint, e.g., `get`, `post`,`put`,`patch`,`delete`
endpoint + + +string + + + + The path for a given endpoint. E.g. `/trackedEntityInstances` or `/dataValueSets`
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Operation + + +
+
+ + + + + + +
Example
+ +

a list of parameters allowed on a given endpoint for specific http method

+ +
discover('post', '/trackedEntityInstances')
+ + + + + + + + + +

(inner) dv(dataElement, value) → {object}

+ + + + + + +
+ Converts a dataElement and value into a DSHI2 dataValue object +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
dataElement + + +string + + + + A data element ID.
value + + +string + + + + The value for that data element.
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +object + + +
+
+ + + + + + +
Example
+ +
dv('f7n9E0hX8qk', 12)
+ + + + + + + + + +

(inner) findAttributeValue(trackedEntityInstance, attributeDisplayName) → {string}

+ + + + + + +
+ Gets an attribute value by its case-insensitive display name +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
trackedEntityInstance + + +Object + + + + A tracked entity instance (TEI) object
attributeDisplayName + + +string + + + + The 'displayName' to search for in the TEI's attributes
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +string + + +
+
+ + + + + + +
Example
+ +
findAttributeValue(state.data.trackedEntityInstances[0], 'first name')
+ + + + + + + + + +

(inner) get(resourceType, query, optionsopt, callbackopt) → {Operation}

+ + + + + + +
+ Get data. Generic helper method for getting data of any kind from DHIS2. +- This can be used to get `DataValueSets`,`events`,`trackedEntityInstances`,`etc.` +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
resourceType + + +string + + + + + + + + + + + + The type of resource to get(use its `plural` name). E.g. `dataElements`, `trackedEntityInstances`,`organisationUnits`, etc.
query + + +Object + + + + + + + + + + + + A query object that will limit what resources are retrieved when converted into request params.
options + + +Object + + + + + + <optional>
+ + + + + +
+ + Optional `options` to define URL parameters via params beyond filters, request configuration (e.g. `auth`) and DHIS2 api version to use.
callback + + +function + + + + + + <optional>
+ + + + + +
+ + false + + Optional callback to handle the response
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ state +
+ + + +
+
+ Type +
+
+ +Operation + + +
+
+ + + + + + +
Examples
+ +

all data values for the 'pBOMPrpg1QX' dataset

+ +
get('dataValueSets', {
+  dataSet: 'pBOMPrpg1QX',
+  orgUnit: 'DiszpKrYNg8',
+  period: '201401',
+  fields: '*',
+});
+ +

all programs for an organization unit

+ +
get('programs', { orgUnit: 'TSyzvBiovKh', fields: '*' });
+ +

a single tracked entity instance by a unique external ID

+ +
get('trackedEntityInstances', {
+  ou: 'DiszpKrYNg8',
+  filter: ['flGbXLXCrEo:Eq:124', 'w75KJ2mc4zz:Eq:John'],
+});
+ + + + + + + + + +

(inner) patch(resourceType, path, data, optionsopt, callbackopt) → {Operation}

+ + + + + + +
+ Patch a record. A generic helper function to send partial updates on one or more object properties. +- You are not required to send the full body of object properties. +- This is useful for cases where you don't want or need to update all properties on a object. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
resourceType + + +string + + + + + + + + + + + + The type of resource to be updated. E.g. `dataElements`, `organisationUnits`, etc.
path + + +string + + + + + + + + + + + + The `id` or `path` to the `object` to be updated. E.g. `FTRrcoaog83` or `FTRrcoaog83/{collection-name}/{object-id}`
data + + +Object + + + + + + + + + + + + Data to update. Include only the fields you want to update. E.g. `{name: "New Name"}`
options + + +Object + + + + + + <optional>
+ + + + + +
+ + Optional configuration, including params for the update ({preheatCache: true, strategy: 'UPDATE', mergeMode: 'REPLACE'}). Defaults to `{operationName: 'patch', apiVersion: state.configuration.apiVersion, responseType: 'json'}`
callback + + +function + + + + + + <optional>
+ + + + + +
+ + false + + Optional callback to handle the response
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Operation + + +
+
+ + + + + + +
Example
+ +

a dataElement

+ +
patch('dataElements', 'FTRrcoaog83', { name: 'New Name' });
+ + + + + + + + + +

(inner) update(resourceType, path, data, optionsopt, callbackopt) → {Operation}

+ + + + + + +
+ Update data. A generic helper function to update a resource object of any type. +Updating an object requires to send `all required fields` or the `full body` +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
resourceType + + +string + + + + + + + + + + + + The type of resource to be updated. E.g. `dataElements`, `organisationUnits`, etc.
path + + +string + + + + + + + + + + + + The `id` or `path` to the `object` to be updated. E.g. `FTRrcoaog83` or `FTRrcoaog83/{collection-name}/{object-id}`
data + + +Object + + + + + + + + + + + + Data to update. It requires to send `all required fields` or the `full body`. If you want `partial updates`, use `patch` operation.
options + + +Object + + + + + + <optional>
+ + + + + +
+ + Optional `options` to define URL parameters via params (E.g. `filter`, `dimension` and other import parameters), request config (E.g. `auth`) and the DHIS2 apiVersion.
callback + + +function + + + + + + <optional>
+ + + + + +
+ + false + + Optional callback to handle the response
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Operation + + +
+
+ + + + + + +
Examples
+ +

a program

+ +
update('programs', 'qAZJCrNJK8H', {
+  name: '14e1aa02c3f0a31618e096f2c6d03bed',
+  shortName: '14e1aa02',
+  programType: 'WITHOUT_REGISTRATION',
+});
+ +

an event

+ +
update('events', 'PVqUD2hvU4E', {
+  program: 'eBAyeGv0exc',
+  orgUnit: 'Ngelehun CHC',
+  status: 'COMPLETED',
+  storedBy: 'admin',
+  dataValues: [],
+});
+ +

a trackedEntityInstance

+ +
update('trackedEntityInstances', 'IeQfgUtGPq2', {
+  created: '2015-08-06T21:12:37.256',
+  orgUnit: 'TSyzvBiovKh',
+  createdAtClient: '2015-08-06T21:12:37.256',
+  trackedEntityInstance: 'IeQfgUtGPq2',
+  lastUpdated: '2015-08-06T21:12:37.257',
+  trackedEntityType: 'nEenWmSyUEp',
+  inactive: false,
+  deleted: false,
+  featureType: 'NONE',
+  programOwners: [
+    {
+      ownerOrgUnit: 'TSyzvBiovKh',
+      program: 'IpHINAT79UW',
+      trackedEntityInstance: 'IeQfgUtGPq2',
+    },
+  ],
+  enrollments: [],
+  relationships: [],
+  attributes: [
+    {
+      lastUpdated: '2016-01-12T00:00:00.000',
+      displayName: 'Last name',
+      created: '2016-01-12T00:00:00.000',
+      valueType: 'TEXT',
+      attribute: 'zDhUuAYrxNC',
+      value: 'Russell',
+    },
+    {
+      lastUpdated: '2016-01-12T00:00:00.000',
+      code: 'MMD_PER_NAM',
+      displayName: 'First name',
+      created: '2016-01-12T00:00:00.000',
+      valueType: 'TEXT',
+      attribute: 'w75KJ2mc4zz',
+      value: 'Catherine',
+    },
+  ],
+});
+ +

a dataSet

+ +
update('dataSets', 'lyLU2wR22tC', { name: 'OpenFN Data Set', periodType: 'Weekly' });
+ +

a dataSetNotification

+ +
update('dataSetNotificationTemplates', 'VbQBwdm1wVP', {
+  dataSetNotificationTrigger: 'DATA_SET_COMPLETION',
+  notificationRecipient: 'ORGANISATION_UNIT_CONTACT',
+  name: 'Notification',
+  messageTemplate: 'Hello Updated,
+  deliveryChannels: ['SMS'],
+  dataSets: [],
+});
+ +

a dataElement

+ +
update('dataElements', 'FTRrcoaog83', {
+  aggregationType: 'SUM',
+  domainType: 'AGGREGATE',
+  valueType: 'NUMBER',
+  name: 'Paracetamol',
+  shortName: 'Para',
+});
+ +

a dataElementGroup

+ +
update('dataElementGroups', 'QrprHT61XFk', {
+  name: 'Data Element Group 1',
+  dataElements: [],
+});
+ +

a dataElementGroupSet

+ +
update('dataElementGroupSets', 'VxWloRvAze8', {
+  name: 'Data Element Group Set 4',
+  dataDimension: true,
+  shortName: 'DEGS4',
+  dataElementGroups: [],
+});
+ +

a dataValueSet

+ +
update('dataValueSets', 'AsQj6cDsUq4', {
+  dataElement: 'f7n9E0hX8qk',
+  period: '201401',
+  orgUnit: 'DiszpKrYNg8',
+  value: '12',
+});
+ +

a dataValueSet with related dataValues

+ +
update('dataValueSets', 'Ix2HsbDMLea', {
+  dataSet: 'pBOMPrpg1QX',
+  completeDate: '2014-02-03',
+  period: '201401',
+  orgUnit: 'DiszpKrYNg8',
+  dataValues: [
+    {
+      dataElement: 'f7n9E0hX8qk',
+      value: '1',
+    },
+    {
+      dataElement: 'Ix2HsbDMLea',
+      value: '2',
+    },
+    {
+      dataElement: 'eY5ehpbEsB7',
+      value: '3',
+    },
+  ],
+});
+ +

a single enrollment

+ +
update('enrollments', 'CmsHzercTBa' {
+  trackedEntityInstance: 'bmshzEacgxa',
+  orgUnit: 'TSyzvBiovKh',
+  program: 'gZBxv9Ujxg0',
+  enrollmentDate: '2013-10-17',
+  incidentDate: '2013-10-17',
+});
+ + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/lib/Adaptor.js b/lib/Adaptor.js index f13f82d..5fe3d9b 100644 --- a/lib/Adaptor.js +++ b/lib/Adaptor.js @@ -659,7 +659,7 @@ function discover(httpMethod, endpoint) { * patch('dataElements', 'FTRrcoaog83', { name: 'New Name' }); */ // TODO: @Elias, can this be deleted in favor of update? How does DHIS2 handle PATCH vs PUT? -// I need to investigate on this. But I think DHIS 2 forces to send all properties back when we do an update. If that's confirmed then this may be needed. +// I need to investigate on this. But I think DHIS2 forces to send all properties back when we do an update. If that's confirmed then this may be needed. function patch(resourceType, path, data, options = {}, callback = false) { diff --git a/lib/Utils.js b/lib/Utils.js index fbb7aeb..b607be4 100644 --- a/lib/Utils.js +++ b/lib/Utils.js @@ -38,8 +38,8 @@ class Log { exports.Log = Log; -function buildUrl(path, hostUrl, apiVersion) { - const pathSuffix = apiVersion ? `/${apiVersion}${path}` : `${path}`; +function buildUrl(urlString, hostUrl, apiVersion) { + const pathSuffix = apiVersion ? `/${apiVersion}${urlString}` : `${urlString}`; return hostUrl + '/api' + pathSuffix; } // Write a unit test for this one diff --git a/src/Adaptor.js b/src/Adaptor.js index 01bc698..07549c3 100644 --- a/src/Adaptor.js +++ b/src/Adaptor.js @@ -614,7 +614,7 @@ export function discover(httpMethod, endpoint) { * patch('dataElements', 'FTRrcoaog83', { name: 'New Name' }); */ // TODO: @Elias, can this be deleted in favor of update? How does DHIS2 handle PATCH vs PUT? -// I need to investigate on this. But I think DHIS 2 forces to send all properties back when we do an update. If that's confirmed then this may be needed. +// I need to investigate on this. But I think DHIS2 forces to send all properties back when we do an update. If that's confirmed then this may be needed. export function patch( resourceType, path, diff --git a/src/Utils.js b/src/Utils.js index 1a0cd94..e901135 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -22,8 +22,8 @@ export class Log { } } -export function buildUrl(path, hostUrl, apiVersion) { - const pathSuffix = apiVersion ? `/${apiVersion}${path}` : `${path}`; +export function buildUrl(urlString, hostUrl, apiVersion) { + const pathSuffix = apiVersion ? `/${apiVersion}${urlString}` : `${urlString}`; return hostUrl + '/api' + pathSuffix; } diff --git a/test/SetupFixtures.js b/test/SetupFixtures.js index 40ed888..18ec69a 100644 --- a/test/SetupFixtures.js +++ b/test/SetupFixtures.js @@ -189,7 +189,7 @@ export const permissions = { jobTitle: 'Super user', lastUpdated: '2021-03-08T08:36:44.531', employer: 'DHIS', - introduction: 'I am the super user of DHIS 2', + introduction: 'I am a super user of DHIS2', languages: 'English', created: '2013-04-18T17:15:08.407', lastCheckedInterpretations: '2021-03-08T08:36:44.531', diff --git a/test/integration.js b/test/integration.js index 95cba6c..118a1e0 100644 --- a/test/integration.js +++ b/test/integration.js @@ -3,20 +3,6 @@ const { create, execute, get, update } = require('../src/Adaptor'); const crypto = require('crypto'); const { upsert } = require('../lib/Adaptor'); -// const getRandomOrganisationUnitPayload = user => { -// const name = crypto.randomBytes(16).toString('hex'); -// const shortName = name.substring(0, 5); -// const displayName = name; -// const openingDate = new Date().toISOString(); -// return { name, shortName, displayName, openingDate, users: [user] }; -// }; - -// const getRandomProgramStagePayload = program => { -// const name = crypto.randomBytes(16).toString('hex'); -// const displayName = name; -// return { name, displayName, program }; -// }; - const getRandomProgramPayload = () => { const name = crypto.randomBytes(16).toString('hex'); const shortName = name.substring(0, 5); @@ -34,6 +20,10 @@ describe('Integration tests', () => { password: 'district', hostUrl: 'https://play.dhis2.org/2.36.6', }, + program: 'IpHINAT79UW', + orgUnit: 'DiszpKrYNg8', + trackedEntityInstance: 'uhubxsfLanV', + programStage: 'eaDHS084uMp', }; done(); }); @@ -42,31 +32,28 @@ describe('Integration tests', () => { it('should create an event program', async () => { const state = { ...fixture.initialState, - data: { program: getRandomProgramPayload() }, + data: getRandomProgramPayload(), }; - const finalState = await execute( - create('programs', state => state.data.program) - )(state); + const finalState = await execute(create('programs', state => state.data))( + state + ); expect(finalState.data.status).to.eq('OK'); }); it('should create a single event', async () => { - const state = { - ...fixture.initialState, - data: { - program: 'eBAyeGv0exc', - orgUnit: 'DiszpKrYNg8', - status: 'COMPLETED', - }, - }; + const state = { ...fixture.initialState }; - const finalState = await execute(create('events', state => state.data))( - state - ); - - console.log('FINAL STATE', finalState); + const finalState = await execute( + create('events', state => ({ + program: state.program, + orgUnit: state.orgUnit, + trackedEntityInstance: state.trackedEntityInstance, + programStage: state.programStage, + status: 'COMPLETED', + })) + )(state); expect(finalState.data.status).to.eq('OK'); }); @@ -148,28 +135,51 @@ describe('Integration tests', () => { it('should update an event program', async () => { const state = { ...fixture.initialState, - program: 'eBAyeGv0exc', - data: { program: getRandomProgramPayload() }, + eventProgram: 'ZHXVrZu5K90', }; const response = await execute( update( 'programs', - state => state.program, - state => state.data.program + state => state.eventProgram, + getRandomProgramPayload() ) )(state); expect(response.data.status).to.eq('OK'); }); - it('should update a single event', async () => { + it.only('should update a single event', async () => { const state = { ...fixture.initialState, - event: 'OZ3mVgaIAqw', + event: 'rBjxtO8npTb', data: { - program: 'eBAyeGv0exc', + href: 'https://play.dhis2.org/2.36.6/api/events/rBjxtO8npTb', + event: 'rBjxtO8npTb', + status: 'ACTIVE', + program: 'M3xtLkYBlKI', + programStage: 'CWaAcQYKVpq', + enrollment: 'V8uPJuhvlL7', + enrollmentStatus: 'ACTIVE', orgUnit: 'DiszpKrYNg8', - status: 'COMPLETED', + orgUnitName: 'Ngelehun CHC', + trackedEntityInstance: 'dNpxRu1mWG5', + relationships: [], + eventDate: '2021-09-26T00:00:00.000', + dueDate: '2021-09-27T00:00:00.000', + storedBy: 'system', + dataValues: [], + notes: [], + followup: false, + deleted: false, + created: '2019-09-26T23:58:59.641', + lastUpdated: '2019-09-27T00:02:11.604', + createdAtClient: '2019-09-26T23:58:59.641', + lastUpdatedAtClient: '2019-09-27T00:02:11.604', + attributeOptionCombo: 'HllvX50cXC0', + attributeCategoryOptions: 'xYerKDKCefk', + assignedUser: 'DXyJmlo9rge', + assignedUserUsername: 'android', + assignedUserDisplayName: 'John Barnes', }, }; const finalState = await execute( @@ -204,83 +214,63 @@ describe('Integration tests', () => { expect(finalState.data.status).to.eq('OK'); }); - it('should update a single dataValueSet', async () => { + it('should update a single dataSet', async () => { const state = { ...fixture.initialState, data: { - dataElement: 'f7n9E0hX8qk', - period: '201401', - orgUnit: 'DiszpKrYNg8', - value: '12', - }, - }; - const finalState = await execute( - update('dataValueSets', 'pBOMPrpg1QX', state => state.data) - )(state); - expect(finalState.data.status).to.eql('SUCCESS'); - }); - - it('should update a set of related data values sharing the same period and organisation unit', async () => { - const state = { - ...fixture.initialState, - data: { - dataSet: 'pBOMPrpg1QX', - completeDate: '2014-02-03', - period: '201401', - orgUnit: 'DiszpKrYNg8', - dataValues: [ + name: 'Reproductive Health', + shortName: 'Reproductive Health', + displayFormName: 'Reproductive Health', + displayName: 'Reproductive Health', + periodType: 'Monthly', + dataSetElements: [ { - dataElement: 'f7n9E0hX8qk', - value: '1', - }, - { - dataElement: 'Ix2HsbDMLea', - value: '2', - }, - { - dataElement: 'eY5ehpbEsB7', - value: '3', + dataElement: { + id: 'FE82N2sA0YI', + }, + dataSet: { + id: 'QX4ZTUbOt3a', + }, }, ], }, }; - const finalState = await execute( - update('dataValueSets', 'pBOMPrpg1QX', state => state.data) + update('dataSets', 'QX4ZTUbOt3a', state => state.data) )(state); - expect(finalState.data.status).to.eq('SUCCESS'); + expect(finalState.data.status).to.eql('OK'); }); }); -}); -describe('get', () => { - const state = { - configuration: { - username: 'admin', - password: 'district', - hostUrl: 'https://play.dhis2.org/2.36.4', - }, - data: {}, - }; + describe('get', () => { + const state = { + configuration: { + username: 'admin', + password: 'district', + hostUrl: 'https://play.dhis2.org/2.36.4', + }, + data: {}, + }; - it('should get dataValueSets matching the query specified', async () => { - const finalState = await execute( - get('dataValueSets', { - dataSet: 'pBOMPrpg1QX', - orgUnit: 'DiszpKrYNg8', - period: '201401', - fields: '*', - }) - )(state); + it('should get dataValueSets matching the query specified', async () => { + const finalState = await execute( + get('dataValueSets', { + dataSet: 'pBOMPrpg1QX', + orgUnit: 'DiszpKrYNg8', + period: '201401', + fields: '*', + }) + )(state); - expect(finalState.data.dataValues.length).to.gte(1); - }); + expect(finalState.data.dataValues.length).to.gte(1); + }); - it('should get all programs in the organisation unit TSyzvBiovKh', async () => { - const response = await execute( - get('programs', { orgUnit: 'TSyzvBiovKh', fields: '*' }) - )(state); - expect(response.data.programs.length).to.gte(1); + it('should get all programs in the organisation unit TSyzvBiovKh', async () => { + const response = await execute( + get('programs', { orgUnit: 'TSyzvBiovKh', fields: '*' }) + )(state); + expect(response.data.programs.length).to.gte(1); + }); }); }); diff --git a/test/mocha.opts b/test/mocha.opts new file mode 100644 index 0000000..43ca4bb --- /dev/null +++ b/test/mocha.opts @@ -0,0 +1 @@ +--timeout 50000 \ No newline at end of file