@oystehr/sdk
Version:
Oystehr SDK
189 lines (186 loc) • 6.28 kB
JavaScript
import { addParamsToSearch } from '../../client/client.js';
/**
* Performs a FHIR search and returns the results as a Bundle resource
*
* @param options FHIR resource type and FHIR search parameters
* @param request optional OystehrClientRequest object
* @returns FHIR Bundle resource
*/
async function search(params, request) {
const { resourceType, params: searchParams } = params;
let paramMap;
if (searchParams) {
paramMap = Object.entries(searchParams).reduce((acc, [_, param]) => {
if (!acc[param.name]) {
acc[param.name] = [];
}
acc[param.name].push(param.value);
return acc;
}, {});
}
const requestBundle = await this.fhirRequest(`/${resourceType}/_search`, 'POST')(paramMap, {
...request,
contentType: 'application/x-www-form-urlencoded',
});
const bundle = {
...requestBundle,
entry: requestBundle.entry,
unbundle: function () {
return this.entry?.map((entry) => entry.resource).filter((entry) => entry !== undefined) ?? [];
},
};
return bundle;
}
async function create(params, request) {
const { resourceType } = params;
return this.fhirRequest(`/${resourceType}`, 'POST')(params, request);
}
async function get({ resourceType, id }, request) {
return this.fhirRequest(`/${resourceType}/${id}`, 'GET')({}, request);
}
async function update(params, request) {
const { id, resourceType } = params;
return this.fhirRequest(`/${resourceType}/${id}`, 'PUT')(params, {
...request,
ifMatch: request?.optimisticLockingVersionId ? `W/"${request.optimisticLockingVersionId}"` : undefined,
});
}
async function patch({ resourceType, id, operations }, request) {
return this.fhirRequest(`/${resourceType}/${id}`, 'PATCH')(operations, {
...request,
contentType: 'application/json-patch+json',
ifMatch: request?.optimisticLockingVersionId ? `W/"${request.optimisticLockingVersionId}"` : undefined,
});
}
async function del({ resourceType, id }, request) {
return this.fhirRequest(`/${resourceType}/${id}`, 'DELETE')({}, request);
}
async function history({ resourceType, id, versionId }, request) {
return this.fhirRequest(`/${resourceType}/${id}/_history${versionId ? `/${versionId}` : ''}`, 'GET')({}, request);
}
function batchInputRequestToBundleEntryItem(request) {
const { method, url } = request;
const baseRequest = {
request: {
method,
url,
},
};
// Escape query string parameters in entry.request.url
if (url.split('?').length > 1) {
const [resource, query] = url.split('?');
const params = query
.split('&')
.map((param) => {
const [name, value] = param.split('=');
return { name, value };
})
.reduce((acc, { name, value }) => {
if (!name) {
return acc;
}
if (!acc[name]) {
acc[name] = [];
}
acc[name].push(value);
return acc;
}, {});
const search = new URLSearchParams();
addParamsToSearch(params, search);
baseRequest.request.url = `${resource}?${search.toString()}`;
}
// GET, DELETE, and HEAD require no further parameters
if (['GET', 'DELETE', 'HEAD'].includes(method)) {
return baseRequest;
}
// PUT updates require a full resource
if (method === 'PUT') {
const { resource } = request;
return {
...baseRequest,
resource: resource,
};
}
// PATCH can be Binary resource or JSON patch
if (method === 'PATCH') {
if ('resource' in request) {
return {
...baseRequest,
resource: request.resource,
};
}
return {
...baseRequest,
resource: {
resourceType: 'Binary',
contentType: 'application/json-patch+json',
data: Buffer.from(JSON.stringify(request.operations), 'utf8').toString('base64'),
},
};
}
// POST creates require a full resource
if (method === 'POST') {
const { resource, fullUrl } = request;
return {
...baseRequest,
resource: resource,
fullUrl,
};
}
throw new Error('Unrecognized method');
}
function bundleRequest(type) {
return async function (input, request) {
return this.fhirRequest('/', 'POST')({
resourceType: 'Bundle',
type,
entry: input.requests.map(batchInputRequestToBundleEntryItem),
}, request);
};
}
const batch = bundleRequest('batch');
const transaction = bundleRequest('transaction');
function formatAddress(address, options) {
const builder = [];
if (address.line) {
builder.push(...address.line);
}
if (address.city || address.state || address.postalCode) {
const cityStateZip = [];
if (address.city) {
cityStateZip.push(address.city);
}
if (address.state) {
cityStateZip.push(address.state);
}
if (address.postalCode) {
cityStateZip.push(address.postalCode);
}
builder.push(cityStateZip.join(', '));
}
if (address.use && (options?.all || options?.use)) {
builder.push('[' + address.use + ']');
}
return builder.join(options?.lineSeparator || ', ').trim();
}
function formatHumanName(name, options) {
const builder = [];
if (name.prefix && options?.prefix !== false) {
builder.push(...name.prefix);
}
if (name.given) {
builder.push(...name.given);
}
if (name.family) {
builder.push(name.family);
}
if (name.suffix && options?.suffix !== false) {
builder.push(...name.suffix);
}
if (name.use && (options?.all || options?.use)) {
builder.push('[' + name.use + ']');
}
return builder.join(' ').trim();
}
export { batch, create, del as delete, formatAddress, formatHumanName, get, history, patch, search, transaction, update };
//# sourceMappingURL=fhir-ext.js.map