rxnormie
Version:
A simple but robust TypeScript client for the RxNorm API — for normies. This package provides a simple and intuitive way to interact with the RxNorm API.
1,157 lines (1,156 loc) • 48.7 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.RxNormie = void 0;
const axios_1 = __importDefault(require("axios"));
/**
* RxNormie - A TypeScript SDK for the RxNorm API
*/
class RxNormie {
/**
* Creates a new instance of the RxNormie SDK
* @param options Configuration options for the SDK
*/
constructor(options) {
const { apiKey, format = 'json' } = options || {};
this.format = format;
this.api = axios_1.default.create({
baseURL: 'https://rxnav.nlm.nih.gov/REST',
params: apiKey ? { apiKey } : {}
});
}
/**
* Helper method to handle XML responses
* @param response The XML response string
* @param pattern The regex pattern to extract data
* @param defaultValue Default value if no match is found
* @returns Extracted value or default value
*/
extractFromXml(response, pattern, defaultValue = '') {
const match = response.match(pattern);
return match ? match[1] : defaultValue;
}
/**
* Helper method to handle errors
* @param error The error object
* @param methodName The name of the method where the error occurred
* @returns Appropriate error value based on the return type
*/
handleError(error, methodName) {
console.error(`Error in ${methodName}:`, error);
// For methods that return arrays, return empty array
if (methodName === 'findRelatedNDCs' ||
methodName === 'getAllConceptsByStatus' ||
methodName === 'getAllConceptsByTTY' ||
methodName === 'getAllHistoricalNDCs' ||
methodName === 'getAllNDCsByStatus' ||
methodName === 'getAllProperties' ||
methodName === 'getApproximateMatch' ||
methodName === 'getDisplayTerms' ||
methodName === 'getIdTypes' ||
methodName === 'getMultiIngredBrand' ||
methodName === 'getNDCProperties' ||
methodName === 'getNDCs' ||
methodName === 'getPropCategories' ||
methodName === 'getPropNames' ||
methodName === 'getReformulationConcepts' ||
methodName === 'getRelaTypes' ||
methodName === 'getRelatedByRelationship' ||
methodName === 'getRelatedByType' ||
methodName === 'getSourceTypes' ||
methodName === 'getSpellingSuggestions' ||
methodName === 'getTermTypes') {
return [];
}
// For all other methods, return null
return null;
}
/**
* Filter by property
* @param rxcui RxNorm concept ID
* @param propName Property name
* @param propValues Property values (comma-delimited)
* @returns RxCUI if the predicate is true, null otherwise
*/
async filterByProperty(rxcui, propName, propValues) {
try {
const response = await this.api.get(`/rxcui/${rxcui}/filter.${this.format}`, {
params: {
propName,
propValues
}
});
if (this.format === 'json') {
return response.data.rxcui || null;
}
else {
const rxcuiMatch = this.extractFromXml(response.data, /<rxcui>(.*?)<\/rxcui>/);
return rxcuiMatch || null;
}
}
catch (error) {
return this.handleError(error, 'filterByProperty');
}
}
/**
* Find NDCs related to a given NDC by concept, product, or drug
* @param ndc The NDC code to find related NDCs for
* @param relation The relation type: 'concept', 'product', or 'drug'
* @param ndcStatus Optional status filter: 'active', 'obsolete', 'alien', or 'ALL'
* @returns An array of related NDC information objects
*/
async findRelatedNDCs(ndc, relation, ndcStatus = 'active') {
var _a;
try {
const response = await this.api.get(`/relatedndc.${this.format}`, {
params: {
ndc,
relation,
ndcstatus: ndcStatus
}
});
if (this.format === 'json') {
return ((_a = response.data.ndcInfoList) === null || _a === void 0 ? void 0 : _a.ndcInfo) || [];
}
else {
const ndcInfoMatches = response.data.match(/<ndcInfo>(.*?)<\/ndcInfo>/g);
if (!ndcInfoMatches)
return [];
return ndcInfoMatches.map((ndcInfoXml) => {
return {
ndc11: this.extractFromXml(ndcInfoXml, /<ndc11>(.*?)<\/ndc11>/),
status: this.extractFromXml(ndcInfoXml, /<status>(.*?)<\/status>/),
rxcui: this.extractFromXml(ndcInfoXml, /<rxcui>(.*?)<\/rxcui>/),
conceptName: this.extractFromXml(ndcInfoXml, /<conceptName>(.*?)<\/conceptName>/),
conceptStatus: this.extractFromXml(ndcInfoXml, /<conceptStatus>(.*?)<\/conceptStatus>/),
tty: this.extractFromXml(ndcInfoXml, /<tty>(.*?)<\/tty>/)
};
});
}
}
catch (error) {
return this.handleError(error, 'findRelatedNDCs');
}
}
/**
* Find RxCUI by ID
* @param id The identifier to look up
* @param idType The type of identifier (e.g., 'NDC', 'RXCUI', etc.)
* @returns An IdGroup object containing the RxNorm IDs
*/
async findRxcuiById(id, idType) {
var _a, _b;
try {
const response = await this.api.get(`/rxcui.${this.format}`, {
params: {
idtype: idType,
id
}
});
if (this.format === 'json') {
return response.data.idGroup || null;
}
else {
const idGroupXml = ((_a = response.data.match(/<idGroup>(.*?)<\/idGroup>/s)) === null || _a === void 0 ? void 0 : _a[1]) || '';
const rxnormIds = ((_b = idGroupXml.match(/<rxnormId>(.*?)<\/rxnormId>/g)) === null || _b === void 0 ? void 0 : _b.map((id) => this.extractFromXml(id, /<rxnormId>(.*?)<\/rxnormId>/))) || [];
return {
name: this.extractFromXml(idGroupXml, /<name>(.*?)<\/name>/),
idType: this.extractFromXml(idGroupXml, /<idType>(.*?)<\/idType>/),
id: this.extractFromXml(idGroupXml, /<id>(.*?)<\/id>/),
rxnormId: rxnormIds
};
}
}
catch (error) {
return this.handleError(error, 'findRxcuiById');
}
}
/**
* Find RxCUI by name
* @param name The name to search for
* @param searchType The type of search ('Exact' or 'Contains')
* @returns An IdGroup object containing the RxNorm IDs
*/
async findRxcuiByString(name, searchType = 'Exact') {
var _a, _b;
try {
const response = await this.api.get(`/rxcui.${this.format}`, {
params: {
name,
search: searchType
}
});
if (this.format === 'json') {
return response.data.idGroup || null;
}
else {
const idGroupXml = ((_a = response.data.match(/<idGroup>(.*?)<\/idGroup>/s)) === null || _a === void 0 ? void 0 : _a[1]) || '';
const rxnormIds = ((_b = idGroupXml.match(/<rxnormId>(.*?)<\/rxnormId>/g)) === null || _b === void 0 ? void 0 : _b.map((id) => this.extractFromXml(id, /<rxnormId>(.*?)<\/rxnormId>/))) || [];
return {
name: this.extractFromXml(idGroupXml, /<name>(.*?)<\/name>/),
idType: this.extractFromXml(idGroupXml, /<idType>(.*?)<\/idType>/),
id: this.extractFromXml(idGroupXml, /<id>(.*?)<\/id>/),
rxnormId: rxnormIds
};
}
}
catch (error) {
return this.handleError(error, 'findRxcuiByString');
}
}
/**
* Get all concepts by status
* @param status The status to filter by
* @returns An array of MinConcept objects
*/
async getAllConceptsByStatus(status) {
var _a;
try {
const response = await this.api.get(`/allstatus.${this.format}`, {
params: {
status
}
});
if (this.format === 'json') {
return ((_a = response.data.minConceptGroup) === null || _a === void 0 ? void 0 : _a.minConcept) || [];
}
else {
const minConceptMatches = response.data.match(/<minConcept>(.*?)<\/minConcept>/g);
if (!minConceptMatches)
return [];
return minConceptMatches.map((conceptXml) => {
return {
rxcui: this.extractFromXml(conceptXml, /<rxcui>(.*?)<\/rxcui>/),
name: this.extractFromXml(conceptXml, /<name>(.*?)<\/name>/),
tty: this.extractFromXml(conceptXml, /<tty>(.*?)<\/tty>/)
};
});
}
}
catch (error) {
return this.handleError(error, 'getAllConceptsByStatus');
}
}
/**
* Get all concepts by term type
* @param tty The term type to filter by
* @returns An array of MinConcept objects
*/
async getAllConceptsByTTY(tty) {
var _a;
try {
const response = await this.api.get(`/allconcepts.${this.format}`, {
params: {
tty
}
});
if (this.format === 'json') {
return ((_a = response.data.minConceptGroup) === null || _a === void 0 ? void 0 : _a.minConcept) || [];
}
else {
const minConceptMatches = response.data.match(/<minConcept>(.*?)<\/minConcept>/g);
if (!minConceptMatches)
return [];
return minConceptMatches.map((conceptXml) => {
return {
rxcui: this.extractFromXml(conceptXml, /<rxcui>(.*?)<\/rxcui>/),
name: this.extractFromXml(conceptXml, /<name>(.*?)<\/name>/),
tty: this.extractFromXml(conceptXml, /<tty>(.*?)<\/tty>/)
};
});
}
}
catch (error) {
return this.handleError(error, 'getAllConceptsByTTY');
}
}
/**
* Get all historical NDCs for a concept
* @param rxcui The RxNorm concept ID
* @returns An array of HistoricalNDC objects
*/
async getAllHistoricalNDCs(rxcui) {
var _a;
try {
const response = await this.api.get(`/rxcui/${rxcui}/allhistoricalndcs.${this.format}`);
if (this.format === 'json') {
return ((_a = response.data.historicalNdcList) === null || _a === void 0 ? void 0 : _a.historicalNdc) || [];
}
else {
const ndcMatches = response.data.match(/<historicalNdc>(.*?)<\/historicalNdc>/g);
if (!ndcMatches)
return [];
return ndcMatches.map((ndcXml) => {
return {
ndc: this.extractFromXml(ndcXml, /<ndc>(.*?)<\/ndc>/),
startDate: this.extractFromXml(ndcXml, /<startDate>(.*?)<\/startDate>/),
endDate: this.extractFromXml(ndcXml, /<endDate>(.*?)<\/endDate>/)
};
});
}
}
catch (error) {
return this.handleError(error, 'getAllHistoricalNDCs');
}
}
/**
* Get all NDCs by status
* @param status The status to filter by
* @returns An array of NDCInfo objects
*/
async getAllNDCsByStatus(status) {
var _a;
try {
const response = await this.api.get(`/allNDCstatus.${this.format}`, {
params: {
status
}
});
if (this.format === 'json') {
return ((_a = response.data.ndcInfoList) === null || _a === void 0 ? void 0 : _a.ndcInfo) || [];
}
else {
const ndcInfoMatches = response.data.match(/<ndcInfo>(.*?)<\/ndcInfo>/g);
if (!ndcInfoMatches)
return [];
return ndcInfoMatches.map((ndcInfoXml) => {
return {
ndc11: this.extractFromXml(ndcInfoXml, /<ndc11>(.*?)<\/ndc11>/),
status: this.extractFromXml(ndcInfoXml, /<status>(.*?)<\/status>/),
rxcui: this.extractFromXml(ndcInfoXml, /<rxcui>(.*?)<\/rxcui>/),
conceptName: this.extractFromXml(ndcInfoXml, /<conceptName>(.*?)<\/conceptName>/),
conceptStatus: this.extractFromXml(ndcInfoXml, /<conceptStatus>(.*?)<\/conceptStatus>/),
tty: this.extractFromXml(ndcInfoXml, /<tty>(.*?)<\/tty>/)
};
});
}
}
catch (error) {
return this.handleError(error, 'getAllNDCsByStatus');
}
}
/**
* Get all properties for a concept
* @param rxcui The RxNorm concept ID
* @param prop The property name to filter by (optional)
* @returns An array of RxNormProperty objects
*/
async getAllProperties(rxcui, prop) {
var _a;
try {
const params = {};
if (prop) {
params.prop = prop;
}
const response = await this.api.get(`/rxcui/${rxcui}/allProperties.${this.format}`, { params });
if (this.format === 'json') {
return ((_a = response.data.propConceptGroup) === null || _a === void 0 ? void 0 : _a.propConcept) || [];
}
else {
const propMatches = response.data.match(/<propConcept>(.*?)<\/propConcept>/g);
if (!propMatches)
return [];
return propMatches.map((propXml) => {
return {
propName: this.extractFromXml(propXml, /<propName>(.*?)<\/propName>/),
propValue: this.extractFromXml(propXml, /<propValue>(.*?)<\/propValue>/)
};
});
}
}
catch (error) {
return this.handleError(error, 'getAllProperties');
}
}
/**
* Get all related information for a concept
* @param rxcui The RxNorm concept ID
* @returns A RelatedGroup object
*/
async getAllRelatedInfo(rxcui) {
var _a;
try {
const response = await this.api.get(`/rxcui/${rxcui}/allrelated.${this.format}`);
if (this.format === 'json') {
return response.data.relatedGroup || null;
}
else {
const relatedGroupXml = ((_a = response.data.match(/<relatedGroup>(.*?)<\/relatedGroup>/s)) === null || _a === void 0 ? void 0 : _a[1]) || '';
const conceptGroupMatches = relatedGroupXml.match(/<conceptGroup>(.*?)<\/conceptGroup>/g);
if (!conceptGroupMatches) {
return {
rxcui: this.extractFromXml(relatedGroupXml, /<rxcui>(.*?)<\/rxcui>/),
name: this.extractFromXml(relatedGroupXml, /<name>(.*?)<\/name>/),
tty: this.extractFromXml(relatedGroupXml, /<tty>(.*?)<\/tty>/),
conceptGroup: []
};
}
const conceptGroups = conceptGroupMatches.map((groupXml) => {
const tty = this.extractFromXml(groupXml, /<tty>(.*?)<\/tty>/);
const conceptPropsMatches = groupXml.match(/<conceptProperties>(.*?)<\/conceptProperties>/g);
if (!conceptPropsMatches) {
return { tty };
}
const conceptProperties = conceptPropsMatches.map((propsXml) => {
return {
rxcui: this.extractFromXml(propsXml, /<rxcui>(.*?)<\/rxcui>/),
name: this.extractFromXml(propsXml, /<name>(.*?)<\/name>/),
synonym: this.extractFromXml(propsXml, /<synonym>(.*?)<\/synonym>/),
tty: this.extractFromXml(propsXml, /<tty>(.*?)<\/tty>/),
language: this.extractFromXml(propsXml, /<language>(.*?)<\/language>/),
suppress: this.extractFromXml(propsXml, /<suppress>(.*?)<\/suppress>/),
umlscui: this.extractFromXml(propsXml, /<umlscui>(.*?)<\/umlscui>/)
};
});
return {
tty,
conceptProperties
};
});
return {
rxcui: this.extractFromXml(relatedGroupXml, /<rxcui>(.*?)<\/rxcui>/),
name: this.extractFromXml(relatedGroupXml, /<name>(.*?)<\/name>/),
tty: this.extractFromXml(relatedGroupXml, /<tty>(.*?)<\/tty>/),
conceptGroup: conceptGroups
};
}
}
catch (error) {
return this.handleError(error, 'getAllRelatedInfo');
}
}
/**
* Get approximate match for a term
* @param term The term to match
* @param maxEntries Maximum number of entries to return
* @param option Options for the match (optional)
* @returns An array of MinConcept objects
*/
async getApproximateMatch(term, maxEntries = 20, option) {
var _a;
try {
const params = {
term,
maxEntries
};
if (option) {
params.option = option;
}
const response = await this.api.get(`/approximateTerm.${this.format}`, { params });
if (this.format === 'json') {
return ((_a = response.data.approximateGroup) === null || _a === void 0 ? void 0 : _a.candidate) || [];
}
else {
const candidateMatches = response.data.match(/<candidate>(.*?)<\/candidate>/g);
if (!candidateMatches)
return [];
return candidateMatches.map((candidateXml) => {
return {
rxcui: this.extractFromXml(candidateXml, /<rxcui>(.*?)<\/rxcui>/),
name: this.extractFromXml(candidateXml, /<name>(.*?)<\/name>/),
tty: this.extractFromXml(candidateXml, /<tty>(.*?)<\/tty>/)
};
});
}
}
catch (error) {
return this.handleError(error, 'getApproximateMatch');
}
}
/**
* Get display terms for auto-completion
* @param term The term to match
* @param option Options for the match (optional)
* @returns An array of display terms
*/
async getDisplayTerms(term, option) {
var _a;
try {
const params = { term };
if (option) {
params.option = option;
}
const response = await this.api.get(`/displaynames.${this.format}`, { params });
if (this.format === 'json') {
return ((_a = response.data.displayTermsList) === null || _a === void 0 ? void 0 : _a.term) || [];
}
else {
const termMatches = response.data.match(/<term>(.*?)<\/term>/g);
if (!termMatches)
return [];
return termMatches.map((termXml) => this.extractFromXml(termXml, /<term>(.*?)<\/term>/));
}
}
catch (error) {
return this.handleError(error, 'getDisplayTerms');
}
}
/**
* Get drug products associated with a specified name
* @param name Name of ingredient, brand, clinical dose form, branded dose form, clinical drug component, or branded drug component
* @param expand Additional result fields to retrieve (e.g., 'psn' for Prescribable Name)
* @returns Drug group containing concept groups with drug information
*/
async getDrugs(name, expand) {
try {
const params = { name };
if (expand) {
params.expand = expand;
}
const response = await this.api.get(`/drugs.${this.format}`, { params });
if (this.format === 'json') {
return response.data.drugGroup || null;
}
else {
const drugGroupMatch = response.data.match(/<drugGroup>([^]*?)<\/drugGroup>/);
if (!drugGroupMatch)
return null;
const drugGroupXml = drugGroupMatch[1];
// Extract concept groups
const conceptGroupMatches = drugGroupXml.match(/<conceptGroup>([^]*?)<\/conceptGroup>/g);
if (!conceptGroupMatches)
return { conceptGroup: [] };
const conceptGroups = conceptGroupMatches.map((conceptGroupXml) => {
const tty = this.extractFromXml(conceptGroupXml, /<tty>(.*?)<\/tty>/);
// Extract concept properties
const conceptPropertiesMatches = conceptGroupXml.match(/<conceptProperties>([^]*?)<\/conceptProperties>/g);
if (!conceptPropertiesMatches)
return { tty };
const conceptProperties = conceptPropertiesMatches.map((conceptPropsXml) => {
return {
rxcui: this.extractFromXml(conceptPropsXml, /<rxcui>(.*?)<\/rxcui>/),
name: this.extractFromXml(conceptPropsXml, /<name>(.*?)<\/name>/) ||
this.extractFromXml(conceptPropsXml, /<n>(.*?)<\/n>/),
synonym: this.extractFromXml(conceptPropsXml, /<synonym>(.*?)<\/synonym>/),
tty: this.extractFromXml(conceptPropsXml, /<tty>(.*?)<\/tty>/),
language: this.extractFromXml(conceptPropsXml, /<language>(.*?)<\/language>/),
suppress: this.extractFromXml(conceptPropsXml, /<suppress>(.*?)<\/suppress>/),
psn: this.extractFromXml(conceptPropsXml, /<psn>(.*?)<\/psn>/)
};
});
return {
tty,
conceptProperties
};
});
return {
conceptGroup: conceptGroups
};
}
}
catch (error) {
return this.handleError(error, 'getDrugs');
}
}
/**
* Get ID types
* @returns An array of ID types
*/
async getIdTypes() {
var _a;
try {
const response = await this.api.get(`/idtypes.${this.format}`);
if (this.format === 'json') {
return ((_a = response.data.idTypeList) === null || _a === void 0 ? void 0 : _a.idName) || [];
}
else {
const idNameMatches = response.data.match(/<idName>(.*?)<\/idName>/g);
if (!idNameMatches)
return [];
return idNameMatches.map((idNameXml) => this.extractFromXml(idNameXml, /<idName>(.*?)<\/idName>/));
}
}
catch (error) {
return this.handleError(error, 'getIdTypes');
}
}
/**
* Get brands containing specified ingredients
* @param ingredients Comma-delimited list of ingredients
* @returns An array of MinConcept objects
*/
async getMultiIngredBrand(ingredients) {
var _a;
try {
const response = await this.api.get(`/brands.${this.format}`, {
params: {
ingredients
}
});
if (this.format === 'json') {
return ((_a = response.data.minConceptGroup) === null || _a === void 0 ? void 0 : _a.minConcept) || [];
}
else {
const minConceptMatches = response.data.match(/<minConcept>(.*?)<\/minConcept>/g);
if (!minConceptMatches)
return [];
return minConceptMatches.map((conceptXml) => {
return {
rxcui: this.extractFromXml(conceptXml, /<rxcui>(.*?)<\/rxcui>/),
name: this.extractFromXml(conceptXml, /<name>(.*?)<\/name>/),
tty: this.extractFromXml(conceptXml, /<tty>(.*?)<\/tty>/)
};
});
}
}
catch (error) {
return this.handleError(error, 'getMultiIngredBrand');
}
}
/**
* Get NDC properties
* @param id The NDC code
* @returns An array of NDC properties
*/
async getNDCProperties(id) {
var _a;
try {
const response = await this.api.get(`/ndcproperties.${this.format}`, {
params: {
id
}
});
if (this.format === 'json') {
return ((_a = response.data.ndcPropertyList) === null || _a === void 0 ? void 0 : _a.ndcProperty) || [];
}
else {
const ndcPropertyMatches = response.data.match(/<ndcProperty>(.*?)<\/ndcProperty>/g);
if (!ndcPropertyMatches)
return [];
return ndcPropertyMatches.map((propertyXml) => {
return {
propertyName: this.extractFromXml(propertyXml, /<propertyName>(.*?)<\/propertyName>/),
propertyValue: this.extractFromXml(propertyXml, /<propertyValue>(.*?)<\/propertyValue>/)
};
});
}
}
catch (error) {
return this.handleError(error, 'getNDCProperties');
}
}
/**
* Get NDC status
* @param ndc The NDC code
* @returns NDC status information
*/
async getNDCStatus(ndc) {
var _a;
try {
const response = await this.api.get(`/ndcstatus.${this.format}`, {
params: {
ndc
}
});
if (this.format === 'json') {
return response.data.ndcStatus || null;
}
else {
const ndcStatusXml = ((_a = response.data.match(/<ndcStatus>(.*?)<\/ndcStatus>/s)) === null || _a === void 0 ? void 0 : _a[1]) || '';
return {
status: this.extractFromXml(ndcStatusXml, /<status>(.*?)<\/status>/),
comment: this.extractFromXml(ndcStatusXml, /<comment>(.*?)<\/comment>/)
};
}
}
catch (error) {
return this.handleError(error, 'getNDCStatus');
}
}
/**
* Get NDCs for a concept
* @param rxcui The RxNorm concept ID
* @returns An array of NDC codes
*/
async getNDCs(rxcui) {
var _a;
try {
const response = await this.api.get(`/rxcui/${rxcui}/ndcs.${this.format}`);
if (this.format === 'json') {
return ((_a = response.data.ndcList) === null || _a === void 0 ? void 0 : _a.ndc) || [];
}
else {
const ndcMatches = response.data.match(/<ndc>(.*?)<\/ndc>/g);
if (!ndcMatches)
return [];
return ndcMatches.map((ndcXml) => this.extractFromXml(ndcXml, /<ndc>(.*?)<\/ndc>/));
}
}
catch (error) {
return this.handleError(error, 'getNDCs');
}
}
/**
* Get property categories
* @returns An array of property categories
*/
async getPropCategories() {
var _a;
try {
const response = await this.api.get(`/propCategories.${this.format}`);
if (this.format === 'json') {
return ((_a = response.data.propCategoryList) === null || _a === void 0 ? void 0 : _a.propCategory) || [];
}
else {
const propCategoryMatches = response.data.match(/<propCategory>(.*?)<\/propCategory>/g);
if (!propCategoryMatches)
return [];
return propCategoryMatches.map((categoryXml) => {
return {
category: this.extractFromXml(categoryXml, /<category>(.*?)<\/category>/)
};
});
}
}
catch (error) {
return this.handleError(error, 'getPropCategories');
}
}
/**
* Get property names
* @param category The property category (optional)
* @returns An array of property names
*/
async getPropNames(category) {
var _a;
try {
const params = {};
if (category) {
params.category = category;
}
const response = await this.api.get(`/propnames.${this.format}`, { params });
if (this.format === 'json') {
return ((_a = response.data.propNameList) === null || _a === void 0 ? void 0 : _a.propName) || [];
}
else {
const propNameMatches = response.data.match(/<propName>(.*?)<\/propName>/g);
if (!propNameMatches)
return [];
return propNameMatches.map((nameXml) => {
return {
name: this.extractFromXml(nameXml, /<name>(.*?)<\/name>/),
category: this.extractFromXml(nameXml, /<category>(.*?)<\/category>/)
};
});
}
}
catch (error) {
return this.handleError(error, 'getPropNames');
}
}
/**
* Get proprietary information for a concept
* @param rxcui The RxNorm concept ID
* @param sourceTypes Comma-delimited list of source types (optional)
* @returns Proprietary information
*/
async getProprietaryInformation(rxcui, sourceTypes) {
var _a;
try {
const params = {};
if (sourceTypes) {
params.sourcetypes = sourceTypes;
}
const response = await this.api.get(`/rxcui/${rxcui}/proprietary.${this.format}`, { params });
if (this.format === 'json') {
return response.data.proprietaryInfo || null;
}
else {
const proprietaryInfoXml = ((_a = response.data.match(/<proprietaryInfo>(.*?)<\/proprietaryInfo>/s)) === null || _a === void 0 ? void 0 : _a[1]) || '';
const proprietaryMatches = proprietaryInfoXml.match(/<proprietary>(.*?)<\/proprietary>/g);
if (!proprietaryMatches) {
return {
rxcui: this.extractFromXml(proprietaryInfoXml, /<rxcui>(.*?)<\/rxcui>/),
proprietary: []
};
}
const proprietary = proprietaryMatches.map((propXml) => {
return {
sourceType: this.extractFromXml(propXml, /<sourceType>(.*?)<\/sourceType>/),
rxaui: this.extractFromXml(propXml, /<rxaui>(.*?)<\/rxaui>/),
code: this.extractFromXml(propXml, /<code>(.*?)<\/code>/),
source: this.extractFromXml(propXml, /<source>(.*?)<\/source>/),
suppressible: this.extractFromXml(propXml, /<suppressible>(.*?)<\/suppressible>/),
tty: this.extractFromXml(propXml, /<tty>(.*?)<\/tty>/),
str: this.extractFromXml(propXml, /<str>(.*?)<\/str>/)
};
});
return {
rxcui: this.extractFromXml(proprietaryInfoXml, /<rxcui>(.*?)<\/rxcui>/),
proprietary
};
}
}
catch (error) {
return this.handleError(error, 'getProprietaryInformation');
}
}
/**
* Get reformulation concepts
* @param rxcui The RxNorm concept ID
* @returns An array of MinConcept objects
*/
async getReformulationConcepts(rxcui) {
var _a;
try {
const response = await this.api.get(`/reformulationConcepts.${this.format}`, {
params: {
rxcui
}
});
if (this.format === 'json') {
return ((_a = response.data.reformulationConcepts) === null || _a === void 0 ? void 0 : _a.reformulationConcept) || [];
}
else {
const conceptMatches = response.data.match(/<reformulationConcept>(.*?)<\/reformulationConcept>/g);
if (!conceptMatches)
return [];
return conceptMatches.map((conceptXml) => {
return {
rxcui: this.extractFromXml(conceptXml, /<rxcui>(.*?)<\/rxcui>/),
name: this.extractFromXml(conceptXml, /<name>(.*?)<\/name>/),
tty: this.extractFromXml(conceptXml, /<tty>(.*?)<\/tty>/)
};
});
}
}
catch (error) {
return this.handleError(error, 'getReformulationConcepts');
}
}
/**
* Get relationship types
* @returns An array of relationship types
*/
async getRelaTypes() {
var _a;
try {
const response = await this.api.get(`/relatypes.${this.format}`);
if (this.format === 'json') {
return ((_a = response.data.relationTypeList) === null || _a === void 0 ? void 0 : _a.relationType) || [];
}
else {
const relaTypeMatches = response.data.match(/<relationType>(.*?)<\/relationType>/g);
if (!relaTypeMatches)
return [];
return relaTypeMatches.map((typeXml) => {
return {
name: this.extractFromXml(typeXml, /<name>(.*?)<\/name>/),
value: this.extractFromXml(typeXml, /<value>(.*?)<\/value>/),
category: this.extractFromXml(typeXml, /<category>(.*?)<\/category>/)
};
});
}
}
catch (error) {
return this.handleError(error, 'getRelaTypes');
}
}
/**
* Get related concepts by relationship
* @param rxcui The RxNorm concept ID
* @param rela The relationship type
* @returns An array of ConceptProperty objects
*/
async getRelatedByRelationship(rxcui, rela) {
var _a, _b, _c;
try {
const response = await this.api.get(`/rxcui/${rxcui}/related.${this.format}`, {
params: {
rela
}
});
if (this.format === 'json') {
return ((_c = (_b = (_a = response.data.relatedGroup) === null || _a === void 0 ? void 0 : _a.conceptGroup) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.conceptProperties) || [];
}
else {
const conceptPropsMatches = response.data.match(/<conceptProperties>(.*?)<\/conceptProperties>/g);
if (!conceptPropsMatches)
return [];
return conceptPropsMatches.map((propsXml) => {
return {
rxcui: this.extractFromXml(propsXml, /<rxcui>(.*?)<\/rxcui>/),
name: this.extractFromXml(propsXml, /<name>(.*?)<\/name>/),
synonym: this.extractFromXml(propsXml, /<synonym>(.*?)<\/synonym>/),
tty: this.extractFromXml(propsXml, /<tty>(.*?)<\/tty>/),
language: this.extractFromXml(propsXml, /<language>(.*?)<\/language>/),
suppress: this.extractFromXml(propsXml, /<suppress>(.*?)<\/suppress>/),
umlscui: this.extractFromXml(propsXml, /<umlscui>(.*?)<\/umlscui>/)
};
});
}
}
catch (error) {
return this.handleError(error, 'getRelatedByRelationship');
}
}
/**
* Get related concepts by type
* @param rxcui The RxNorm concept ID
* @param tty The term type
* @returns An array of ConceptProperty objects
*/
async getRelatedByType(rxcui, tty) {
var _a, _b, _c;
try {
const response = await this.api.get(`/rxcui/${rxcui}/related.${this.format}`, {
params: {
tty
}
});
if (this.format === 'json') {
return ((_c = (_b = (_a = response.data.relatedGroup) === null || _a === void 0 ? void 0 : _a.conceptGroup) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.conceptProperties) || [];
}
else {
const conceptPropsMatches = response.data.match(/<conceptProperties>(.*?)<\/conceptProperties>/g);
if (!conceptPropsMatches)
return [];
return conceptPropsMatches.map((propsXml) => {
return {
rxcui: this.extractFromXml(propsXml, /<rxcui>(.*?)<\/rxcui>/),
name: this.extractFromXml(propsXml, /<name>(.*?)<\/name>/),
synonym: this.extractFromXml(propsXml, /<synonym>(.*?)<\/synonym>/),
tty: this.extractFromXml(propsXml, /<tty>(.*?)<\/tty>/),
language: this.extractFromXml(propsXml, /<language>(.*?)<\/language>/),
suppress: this.extractFromXml(propsXml, /<suppress>(.*?)<\/suppress>/),
umlscui: this.extractFromXml(propsXml, /<umlscui>(.*?)<\/umlscui>/)
};
});
}
}
catch (error) {
return this.handleError(error, 'getRelatedByType');
}
}
/**
* Get RxNorm concept properties
* @param rxcui The RxNorm concept ID
* @returns RxConceptProperties object
*/
async getRxConceptProperties(rxcui) {
var _a;
try {
const response = await this.api.get(`/rxcui/${rxcui}/properties.${this.format}`);
if (this.format === 'json') {
return response.data.properties || null;
}
else {
const propertiesXml = ((_a = response.data.match(/<properties>(.*?)<\/properties>/s)) === null || _a === void 0 ? void 0 : _a[1]) || '';
return {
rxcui: this.extractFromXml(propertiesXml, /<rxcui>(.*?)<\/rxcui>/),
name: this.extractFromXml(propertiesXml, /<name>(.*?)<\/name>/),
synonym: this.extractFromXml(propertiesXml, /<synonym>(.*?)<\/synonym>/),
tty: this.extractFromXml(propertiesXml, /<tty>(.*?)<\/tty>/),
language: this.extractFromXml(propertiesXml, /<language>(.*?)<\/language>/),
suppress: this.extractFromXml(propertiesXml, /<suppress>(.*?)<\/suppress>/),
umlscui: this.extractFromXml(propertiesXml, /<umlscui>(.*?)<\/umlscui>/)
};
}
}
catch (error) {
return this.handleError(error, 'getRxConceptProperties');
}
}
/**
* Get RxNorm name for a concept
* @param rxcui The RxNorm concept ID
* @returns The name of the concept
*/
async getRxNormName(rxcui) {
var _a;
try {
const response = await this.api.get(`/rxcui/${rxcui}.${this.format}`);
if (this.format === 'json') {
return ((_a = response.data.idGroup) === null || _a === void 0 ? void 0 : _a.name) || null;
}
else {
return this.extractFromXml(response.data, /<name>(.*?)<\/name>/) || null;
}
}
catch (error) {
return this.handleError(error, 'getRxNormName');
}
}
/**
* Get RxNorm version information
* @returns RxNorm version information
*/
async getRxNormVersion() {
var _a;
try {
const response = await this.api.get(`/version.${this.format}`);
if (this.format === 'json') {
return response.data.rxnormVersions || null;
}
else {
const versionsXml = ((_a = response.data.match(/<rxnormVersions>(.*?)<\/rxnormVersions>/s)) === null || _a === void 0 ? void 0 : _a[1]) || '';
const versionMatches = versionsXml.match(/<rxnormVersion>(.*?)<\/rxnormVersion>/g);
if (!versionMatches) {
return { rxnormVersion: [] };
}
const rxnormVersion = versionMatches.map((versionXml) => {
return {
version: this.extractFromXml(versionXml, /<version>(.*?)<\/version>/),
releaseDate: this.extractFromXml(versionXml, /<releaseDate>(.*?)<\/releaseDate>/)
};
});
return { rxnormVersion };
}
}
catch (error) {
return this.handleError(error, 'getRxNormVersion');
}
}
/**
* Get a specific property for a concept
* @param rxcui The RxNorm concept ID
* @param propName The property name
* @returns The property value
*/
async getRxProperty(rxcui, propName) {
var _a, _b, _c;
try {
const response = await this.api.get(`/rxcui/${rxcui}/property.${this.format}`, {
params: {
propName
}
});
if (this.format === 'json') {
return ((_c = (_b = (_a = response.data.propConceptGroup) === null || _a === void 0 ? void 0 : _a.propConcept) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.propValue) || null;
}
else {
return this.extractFromXml(response.data, /<propValue>(.*?)<\/propValue>/) || null;
}
}
catch (error) {
return this.handleError(error, 'getRxProperty');
}
}
/**
* Get RxCUI history status
* @param rxcui The RxNorm concept ID
* @returns RxCUI history status information
*/
async getRxcuiHistoryStatus(rxcui) {
var _a;
try {
const response = await this.api.get(`/rxcui/${rxcui}/historystatus.${this.format}`);
if (this.format === 'json') {
return response.data.rxcuiHistoryStatus || null;
}
else {
const statusXml = ((_a = response.data.match(/<rxcuiHistoryStatus>(.*?)<\/rxcuiHistoryStatus>/s)) === null || _a === void 0 ? void 0 : _a[1]) || '';
const historyMatches = statusXml.match(/<history>(.*?)<\/history>/g);
if (!historyMatches) {
return {
rxcui: this.extractFromXml(statusXml, /<rxcui>(.*?)<\/rxcui>/),
status: this.extractFromXml(statusXml, /<status>(.*?)<\/status>/)
};
}
const history = historyMatches.map((historyXml) => {
return {
rxcui: this.extractFromXml(historyXml, /<rxcui>(.*?)<\/rxcui>/),
sab: this.extractFromXml(historyXml, /<sab>(.*?)<\/sab>/),
code: this.extractFromXml(historyXml, /<code>(.*?)<\/code>/),
sab2: this.extractFromXml(historyXml, /<sab2>(.*?)<\/sab2>/),
code2: this.extractFromXml(historyXml, /<code2>(.*?)<\/code2>/),
changeType: this.extractFromXml(historyXml, /<changeType>(.*?)<\/changeType>/),
changeDate: this.extractFromXml(historyXml, /<changeDate>(.*?)<\/changeDate>/)
};
});
return {
rxcui: this.extractFromXml(statusXml, /<rxcui>(.*?)<\/rxcui>/),
status: this.extractFromXml(statusXml, /<status>(.*?)<\/status>/),
history
};
}
}
catch (error) {
return this.handleError(error, 'getRxcuiHistoryStatus');
}
}
/**
* Get source types
* @returns An array of source types
*/
async getSourceTypes() {
var _a;
try {
const response = await this.api.get(`/sourcetypes.${this.format}`);
if (this.format === 'json') {
return ((_a = response.data.sourceTypeList) === null || _a === void 0 ? void 0 : _a.sourceType) || [];
}
else {
const sourceTypeMatches = response.data.match(/<sourceType>(.*?)<\/sourceType>/g);
if (!sourceTypeMatches)
return [];
return sourceTypeMatches.map((typeXml) => {
return {
abbr: this.extractFromXml(typeXml, /<abbr>(.*?)<\/abbr>/),
name: this.extractFromXml(typeXml, /<name>(.*?)<\/name>/)
};
});
}
}
catch (error) {
return this.handleError(error, 'getSourceTypes');
}
}
/**
* Get spelling suggestions for a term
* @param term The term to get suggestions for
* @returns An array of spelling suggestions
*/
async getSpellingSuggestions(term) {
var _a, _b;
try {
const response = await this.api.get(`/spellingsuggestions.${this.format}`, {
params: {
name: term
}
});
if (this.format === 'json') {
return ((_b = (_a = response.data.suggestionGroup) === null || _a === void 0 ? void 0 : _a.suggestionList) === null || _b === void 0 ? void 0 : _b.suggestion) || [];
}
else {
const suggestionMatches = response.data.match(/<suggestion>(.*?)<\/suggestion>/g);
if (!suggestionMatches)
return [];
return suggestionMatches.map((suggestionXml) => this.extractFromXml(suggestionXml, /<suggestion>(.*?)<\/suggestion>/));
}
}
catch (error) {
return this.handleError(error, 'getSpellingSuggestions');
}
}
/**
* Get term types
* @returns An array of term types
*/
async getTermTypes() {
var _a;
try {
const response = await this.api.get(`/termtypes.${this.format}`);
if (this.format === 'json') {
return ((_a = response.data.termTypeList) === null || _a === void 0 ? void 0 : _a.termType) || [];
}
else {
const termTypeMatches = response.data.match(/<termType>(.*?)<\/termType>/g);
if (!termTypeMatches)
return [];
return termTypeMatches.map((typeXml) => {
return {
name: this.extractFromXml(typeXml, /<name>(.*?)<\/name>/),
expanded: this.extractFromXml(typeXml, /<expanded>(.*?)<\/expanded>/)
};
});
}
}
catch (error) {
return this.handleError(error, 'getTermTypes');
}
}
}
exports.RxNormie = RxNormie;