"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.execute = execute;
exports.getCases = getCases;
exports.createCase = createCase;
exports.updateCase = updateCase;
exports.upsertCase = upsertCase;
exports.getReferrals = getReferrals;
exports.createReferrals = createReferrals;
exports.updateReferrals = updateReferrals;
Object.defineProperty(exports, "alterState", {
enumerable: true,
get: function get() {
return _languageCommon.alterState;
}
});
Object.defineProperty(exports, "fn", {
enumerable: true,
get: function get() {
return _languageCommon.fn;
}
});
Object.defineProperty(exports, "combine", {
enumerable: true,
get: function get() {
return _languageCommon.combine;
}
});
Object.defineProperty(exports, "dataPath", {
enumerable: true,
get: function get() {
return _languageCommon.dataPath;
}
});
Object.defineProperty(exports, "dataValue", {
enumerable: true,
get: function get() {
return _languageCommon.dataValue;
}
});
Object.defineProperty(exports, "each", {
enumerable: true,
get: function get() {
return _languageCommon.each;
}
});
Object.defineProperty(exports, "field", {
enumerable: true,
get: function get() {
return _languageCommon.field;
}
});
Object.defineProperty(exports, "fields", {
enumerable: true,
get: function get() {
return _languageCommon.fields;
}
});
Object.defineProperty(exports, "http", {
enumerable: true,
get: function get() {
return _languageCommon.http;
}
});
Object.defineProperty(exports, "lastReferenceValue", {
enumerable: true,
get: function get() {
return _languageCommon.lastReferenceValue;
}
});
Object.defineProperty(exports, "merge", {
enumerable: true,
get: function get() {
return _languageCommon.merge;
}
});
Object.defineProperty(exports, "sourceValue", {
enumerable: true,
get: function get() {
return _languageCommon.sourceValue;
}
});
var _languageCommon = require("@openfn/language-common");
var _Utils = require("./Utils");
var _request = _interopRequireDefault(require("request"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
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; }
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 _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; }
/**
* Execute a sequence of operations.
* Wraps `language-common/execute`, and prepends initial state for http.
* @example
* execute(
* create('foo'),
* delete('bar')
* )(state)
* @function
* @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 = {
references: [],
data: null
};
return function (state) {
return _languageCommon.execute.apply(void 0, [login].concat(operations, [cleanupState]))(_objectSpread({}, initialState, {}, state));
};
}
/**
* Generate an auth string to support multiple types of auth credentials.
* @example
* generateAuthString(state)
* @function
* @param {State} state
* @returns {string}
*/
function generateAuthString(state) {
var auth = state.auth,
configuration = state.configuration;
if (configuration.basicAuth) {
var user = configuration.user,
password = configuration.password;
return 'Basic ' + Buffer.from("".concat(user, ":").concat(password)).toString('base64');
}
var token = auth.token;
return "Bearer ".concat(token);
}
/**
* Execute custom query
* @param {State} state
* @param {object} params
* @param {function} callback
* @returns {State}
*/
function queryHandler(state, params, callback) {
return new Promise(function (resolve, reject) {
(0, _request["default"])(params, function (error, response, body) {
response = (0, _Utils.scrubResponse)(response);
error = (0, _Utils.assembleError)({
error: error,
response: response,
params: params
});
if (error) {
reject(error);
} else {
console.log("Primero says: '".concat(response.statusCode, " ").concat(response.statusMessage, "'"));
var resp = (0, _Utils.tryJson)(body);
if (params.method === 'GET') {
console.log("".concat(resp.data.length, " referrals retrieved from request: ").concat(JSON.stringify(response.request, null, 2), "."));
} else if (params.method === 'PATCH') {
console.log('Referral updated.');
}
var nextState = (0, _languageCommon.composeNextState)(state, resp.data || resp);
if (callback) resolve(callback(nextState));
resolve(nextState);
}
});
});
}
/**
* Logs in to Primero.
* @example
* login(state)
* @function
* @param {State} state - Runtime state.
* @returns {State}
*/
function login(state) {
var _state$configuration = state.configuration,
url = _state$configuration.url,
user = _state$configuration.user,
password = _state$configuration.password;
var body = JSON.stringify({
user: {
user_name: user,
password: password
}
});
var params = {
method: 'POST',
url: "".concat(url, "/api/v2/tokens"),
headers: {
'Content-Type': 'application/json'
},
body: body
};
return new Promise(function (resolve, reject) {
(0, _request["default"])(params, function (error, response, body) {
response = (0, _Utils.scrubResponse)(response);
error = (0, _Utils.assembleError)({
error: error,
response: response,
params: params
});
if (error) {
reject(error);
} else {
var resp = (0, _Utils.tryJson)(body);
resolve(_objectSpread({}, state, {
auth: resp
}));
}
});
});
}
/**
* Removes unserializable keys from the state.
* @example
* cleanupState(state)
* @function
* @param {State} state
* @returns {State}
*/
function cleanupState(state) {
delete state.auth;
return state;
}
/**
* Get cases from Primero
* @public
* @example
* getCases({
* remote: true,
* case_id: '6aeaa66a-5a92-4ff5-bf7a-e59cde07eaaz'
* query: 'sex=male' // optional
* }, callback)
* @function
* @param {object} query - an object with a query param at minimum.
* @param {function} callback - (Optional) Callback function
* @returns {Operation}
*/
function getCases(query, callback) {
return function (state) {
var url = state.configuration.url;
var params = {
method: 'GET',
url: "".concat(url, "/api/v2/cases"),
headers: {
Authorization: generateAuthString(state),
'Content-Type': 'application/json'
},
qs: query
};
return new Promise(function (resolve, reject) {
(0, _request["default"])(params, function (error, response, body) {
response = (0, _Utils.scrubResponse)(response);
error = (0, _Utils.assembleError)({
error: error,
response: response,
params: params
});
if (error) {
reject(error);
} else {
console.log("Primero says: '".concat(response.statusCode, " ").concat(response.statusMessage, "'"));
var resp = (0, _Utils.tryJson)(body);
console.log("".concat(resp.data.length, " cases retrieved from request: ").concat(JSON.stringify(response.request, null, 2), "."));
var nextState = (0, _languageCommon.composeNextState)(state, resp.data);
if (callback) resolve(callback(nextState));
resolve(nextState);
}
});
});
};
}
/**
* Create case in Primero
* @public
* @example
* createCase({
* data: state => data {
* "enabled": true,
* "age": 15,
* "sex": "male",
* "name": "Alex",
* "status": "open",
* "case_id": "6aeaa66a-5a92-4ff5-bf7a-e59cde07eaaz",
* "owned_by": "primero_cp"
* }}, callback)
* @function
* @param {object} params - an object with some case data.
* @param {function} callback - (Optional) Callback function
* @returns {Operation}
*/
function createCase(params, callback) {
return function (state) {
var url = state.configuration.url;
var _expandReferences = (0, _languageCommon.expandReferences)(params)(state),
data = _expandReferences.data;
var requestParams = {
method: 'POST',
url: "".concat(url, "/api/v2/cases"),
headers: {
Authorization: generateAuthString(state),
'Content-Type': 'application/json',
options: {
successCodes: [200, 201, 202, 203, 204]
}
},
json: {
data: data
}
};
return new Promise(function (resolve, reject) {
(0, _request["default"])(requestParams, function (error, response, body) {
response = (0, _Utils.scrubResponse)(response);
error = (0, _Utils.assembleError)({
error: error,
response: response,
params: requestParams
});
if (error) {
reject(error);
} else {
var _resp$body;
var resp = (0, _Utils.tryJson)(body);
console.log("Post succeeded: ".concat(response.statusCode, " ").concat(response.statusMessage));
var nextState = (0, _languageCommon.composeNextState)(state, (_resp$body = resp.body) === null || _resp$body === void 0 ? void 0 : _resp$body.data);
if (callback) resolve(callback(nextState));
resolve(nextState);
}
});
});
};
}
/**
* Update case in Primero
* @public
* @example
* updateCase("7ed1d49f-14c7-4181-8d83-dc8ed1699f08", {
* data: state => data {
* "age": 20,
* "sex": "male",
* "name": "Alex",
* "status": "open",
* "case_id": "6aeaa66a-5a92-4ff5-bf7a-e59cde07eaaz",
* }}, callback)
* @function
* @param {string} id - an ID to use for the update.
* @param {object} params - an object with some case data.
* @param {function} callback - (Optional) Callback function
* @returns {Operation}
*/
function updateCase(id, params, callback) {
return function (state) {
var url = state.configuration.url;
var _expandReferences2 = (0, _languageCommon.expandReferences)(params)(state),
data = _expandReferences2.data;
var requestParams = {
method: 'PATCH',
url: "".concat(url, "/api/v2/cases/").concat(id),
headers: {
Authorization: generateAuthString(state),
'Content-Type': 'application/json'
},
json: {
data: data
}
};
return new Promise(function (resolve, reject) {
(0, _request["default"])(requestParams, function (error, response, body) {
response = (0, _Utils.scrubResponse)(response);
error = (0, _Utils.assembleError)({
error: error,
response: response,
params: {}
});
if (error) {
reject(error);
} else {
var _resp$body2;
var resp = (0, _Utils.tryJson)(body);
var nextState = (0, _languageCommon.composeNextState)(state, (_resp$body2 = resp.body) === null || _resp$body2 === void 0 ? void 0 : _resp$body2.data);
if (callback) resolve(callback(nextState));
resolve(nextState);
}
});
});
};
}
/**
* Upsert case to Primero
* @public
* @example
* upsertCase({
* externalIds: ['case_id'],
* data: state => data {
* "age": 20,
* "sex": "male",
* "name": "Alex",
* "status": "open",
* "case_id": "6aeaa66a-5a92-4ff5-bf7a-e59cde07eaaz",
* }}, callback);
* @function
* @param {object} params - an object with an externalId and some case data.
* @param {function} callback - (Optional) Callback function
* @returns {Operation}
*/
function upsertCase(params, callback) {
return function (state) {
var url = state.configuration.url;
var _expandReferences3 = (0, _languageCommon.expandReferences)(params)(state),
_data = _expandReferences3.data,
externalIds = _expandReferences3.externalIds;
var qs = {
remote: true,
scope: {}
};
externalIds.map(function (x) {
// For every externalId field that is provided, add a key to the
// scope object in our qs (queryString) and set the value for that key to
// whatever value is found IN THE DATA for the given externalId.
return qs[x] = "".concat(_data[x]);
});
var requestParams = {
method: 'GET',
url: "".concat(url, "/api/v2/cases"),
headers: {
Authorization: generateAuthString(state),
'Content-Type': 'application/json'
},
qs: qs
}; // NOTE: while record_id is used in the GET, it must be dropped before -----
// subsequent create or update calls are made as it's not valid in Primero.
delete _data['record_id']; // -------------------------------------------------------------------------
return new Promise(function (resolve, reject) {
(0, _request["default"])(requestParams, function (error, response, body) {
response = (0, _Utils.scrubResponse)(response);
error = (0, _Utils.assembleError)({
error: error,
response: response,
params: {}
});
if (error) {
reject(error);
} else {
var resp = (0, _Utils.tryJson)(body);
if (resp.data.length == 0) {
console.log('No case found. Performing create.');
resolve(createCase({
data: function data(state) {
return _data;
}
}, callback)(state));
} else if (resp.data.length == 1) {
console.log('Case found. Performing update.');
resolve(updateCase(resp.data[0].id, {
data: function data(state) {
// =========== Need clarification on this. Should we test when 'child' does not exist? ===========
var child = _data.child; // NOTE: When performing an upsert, we only add _new_
// services to Primero, as defined by their "unique_id".
// The logic below takes the services array returned by
// Primero as the starting point, and concatenates it with a
// "newServices" array, which includes only those services
// whose "unique_id" values are NOT existing in the Primero
// services array.
var oldServices = resp.data[0].services_section;
if (oldServices && oldServices.length > 0) {
var serviceIds = oldServices.map(function (s) {
return s.unique_id;
});
var newServices = child.services_section.filter(function (os) {
return !serviceIds.includes(os.unique_id);
});
var mergedServices = oldServices.concat(newServices);
return _objectSpread({}, _data, {
child: _objectSpread({}, child, {
services_section: mergedServices
})
});
}
return _data;
}
}, callback)(state));
} else {
reject('Multiple cases found. Try using another externalId and ensure that it is unique.');
}
}
});
});
};
}
/**
* Get referrals for a specific case in Primero
* @public
* @example
* getReferrals(
* {
* externalId: "record_id",
* id: "7ed1d49f-14c7-4181-8d83-dc8ed1699f08"
* }, callback)
* @function
* @param {object} params - an object with an externalId value to use and the id.
* @param {function} callback - (Optional) Callback function
* @returns {Operation}
*/
function getReferrals(params, callback) {
return function (state) {
var url = state.configuration.url;
var _expandReferences4 = (0, _languageCommon.expandReferences)(params)(state),
externalId = _expandReferences4.externalId,
id = _expandReferences4.id;
var requestParams = {};
return new Promise(function (resolve, reject) {
if (externalId === 'record_id') {
console.log('Fetching by record id...');
requestParams = {
method: 'GET',
url: "".concat(url, "/api/v2/cases/").concat(id, "/referrals"),
headers: {
Authorization: generateAuthString(state),
'Content-Type': 'application/json'
}
};
resolve(queryHandler(state, requestParams, callback));
} else {
console.log('Fetching by case id...');
var qs = {
case_id: "".concat(id)
};
requestParams = {
method: 'GET',
url: "".concat(url, "/api/v2/cases"),
headers: {
Authorization: generateAuthString(state),
'Content-Type': 'application/json'
},
qs: qs
};
return new Promise(function (resolve, reject) {
(0, _request["default"])(requestParams, function (error, response, body) {
response = (0, _Utils.scrubResponse)(response);
error = (0, _Utils.assembleError)({
error: error,
response: response,
params: {}
});
if (error) {
reject(error);
} else {
var resp = (0, _Utils.tryJson)(body);
if (resp.data.length == 0) {
console.log('No case found.');
resolve(state);
return state;
} else if (resp.data.length === 1) {
console.log('Case found. Fetching referrals.');
var _id = resp.data[0].id;
requestParams = {
method: 'GET',
url: "".concat(url, "/api/v2/cases/").concat(_id, "/referrals"),
headers: {
Authorization: generateAuthString(state),
'Content-Type': 'application/json'
}
};
resolve(queryHandler(state, requestParams, callback));
} else {
reject('Multiple cases found. Try using another externalId and ensure that it is unique.');
}
}
});
});
}
});
};
}
/**
* Create case in Primero
* @public
* @example
* createReferrals({
* data: {
* "ids": ['case_id'],
* "transitioned_to": "primero_cp",
* "notes": "Creating a referral"
* }}, callback)
* @function
* @param {object} params - an object with some case data.
* @param {function} callback - (Optional) Callback function
* @returns {Operation}
*/
function createReferrals(params, callback) {
return function (state) {
var url = state.configuration.url;
var _expandReferences5 = (0, _languageCommon.expandReferences)(params)(state),
data = _expandReferences5.data;
var requestParams = {
method: 'POST',
url: "".concat(url, "/api/v2/cases/referrals"),
headers: {
Authorization: generateAuthString(state),
'Content-Type': 'application/json',
options: {
successCodes: [200, 201, 202, 203, 204]
}
},
json: {
data: data
}
};
return new Promise(function (resolve, reject) {
(0, _request["default"])(requestParams, function (error, response, body) {
response = (0, _Utils.scrubResponse)(response);
error = (0, _Utils.assembleError)({
error: error,
response: response,
params: requestParams
});
if (error) {
reject(error);
} else {
var resp = (0, _Utils.tryJson)(body);
console.log("Post succeeded: ".concat(response.statusCode, " ").concat(response.statusMessage));
var nextState = (0, _languageCommon.composeNextState)(state, resp.data.body);
if (callback) resolve(callback(nextState));
resolve(nextState);
}
});
});
};
}
/**
* Update referrals for a specific case in Primero
* @public
* @example
* updateReferrals(
* {
* externalId: "record_id",
* id: "7ed1d49f-14c7-4181-8d83-dc8ed1699f08"
* referral_id: "37612f65-3bda-48eb-b526-d31383f94166",
* data: state => state.data
* },
* callback)
* @function
* @param {object} params - an object with an externalId value to use, the id and the referral id to update.
* @param {function} callback - (Optional) Callback function
* @returns {Operation}
*/
function updateReferrals(params, callback) {
return function (state) {
var url = state.configuration.url;
var _expandReferences6 = (0, _languageCommon.expandReferences)(params)(state),
externalId = _expandReferences6.externalId,
id = _expandReferences6.id,
referral_id = _expandReferences6.referral_id,
data = _expandReferences6.data;
var requestParams = {};
return new Promise(function (resolve, reject) {
if (externalId === 'record_id') {
console.log('Updating by record id...');
requestParams = {
method: 'PATCH',
url: "".concat(url, "/api/v2/cases/").concat(id, "/referrals/").concat(referral_id),
headers: {
Authorization: generateAuthString(state),
'Content-Type': 'application/json'
},
json: {
data: data
}
};
resolve(queryHandler(state, requestParams, callback));
} else {
console.log('Updating by case id...');
var qs = {
case_id: "".concat(id)
};
requestParams = {
method: 'GET',
url: "".concat(url, "/api/v2/cases"),
headers: {
Authorization: generateAuthString(state),
'Content-Type': 'application/json'
},
qs: qs
};
return new Promise(function (resolve, reject) {
(0, _request["default"])(requestParams, function (error, response, body) {
response = (0, _Utils.scrubResponse)(response);
error = (0, _Utils.assembleError)({
error: error,
response: response,
params: {}
});
if (error) {
reject(error);
} else {
var resp = (0, _Utils.tryJson)(body);
if (resp.data.length == 0) {
console.log('No case found.');
resolve(state);
return state;
} else if (resp.data.length === 1) {
console.log('Case found. Fetching referrals.');
var _id2 = resp.data[0].id;
requestParams = {
method: 'PATCH',
url: "".concat(url, "/api/v2/cases/").concat(_id2, "/referrals/").concat(referral_id),
headers: {
Authorization: generateAuthString(state),
'Content-Type': 'application/json'
},
json: {
data: data
}
};
resolve(queryHandler(state, requestParams, callback));
} else {
reject('Multiple cases found. Try using another externalId and ensure that it is unique.');
}
}
});
});
}
});
};
}