@fhirfly-io/terminology 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -30,7 +30,7 @@ console.log(npi.data.name);
30
30
  ## Features
31
31
 
32
32
  - **Full TypeScript support** with comprehensive type definitions
33
- - **11 healthcare domains**: NDC, NPI, RxNorm, LOINC, ICD-10, CVX, MVX, FDA Labels, SNOMED CT, Connectivity, Claims
33
+ - **17 healthcare domains**: NDC, NPI, RxNorm, LOINC, ICD-10, CVX, MVX, FDA Labels, SNOMED CT, UCUM, RxClass, HCPCS, MS-DRG, POS, J-Code/NDC Crosswalk, Connectivity, Claims
34
34
  - **Search** with full-text queries, filters, facets, and pagination
35
35
  - **Batch lookups** for efficient bulk operations
36
36
  - **Response shapes**: compact, standard, or full detail levels
@@ -246,6 +246,110 @@ const categories = await client.snomed.categories();
246
246
  const mappings = await client.snomed.mappings("73211009");
247
247
  ```
248
248
 
249
+ ### UCUM (Units of Measure)
250
+
251
+ Unified Code for Units of Measure — lookup, validate, search, and convert healthcare units.
252
+
253
+ ```typescript
254
+ // Look up a UCUM unit
255
+ const unit = await client.ucum.lookup("mg");
256
+ console.log(unit.data.display); // "milligram"
257
+
258
+ // Validate a UCUM expression
259
+ const validation = await client.ucum.validate("mg/dL");
260
+ console.log(validation.data.is_valid); // true
261
+
262
+ // Search for units
263
+ const results = await client.ucum.search({ q: "milligram" });
264
+
265
+ // Convert between units
266
+ const conversion = await client.ucum.convert({
267
+ value: 1000,
268
+ from: "mg",
269
+ to: "g",
270
+ });
271
+ console.log(conversion.data.result); // 1
272
+ ```
273
+
274
+ ### RxClass (Drug Classifications)
275
+
276
+ RxClass drug classification hierarchy from NLM — look up drug classes, search, and find class members.
277
+
278
+ ```typescript
279
+ // Look up a drug class
280
+ const rxclass = await client.rxclass.lookup("N0000175503");
281
+ console.log(rxclass.data.class_name); // "HMG-CoA Reductase Inhibitors"
282
+
283
+ // Search for drug classes
284
+ const results = await client.rxclass.search({
285
+ q: "statin",
286
+ class_type: "EPC",
287
+ });
288
+
289
+ // Get members of a drug class (drugs belonging to the class)
290
+ const members = await client.rxclass.members("N0000175503");
291
+ for (const drug of members.data.members) {
292
+ console.log(`${drug.rxcui}: ${drug.name}`);
293
+ }
294
+ ```
295
+
296
+ ### HCPCS Level II
297
+
298
+ ```typescript
299
+ // Look up a procedure code
300
+ const hcpcs = await client.hcpcs.lookup("A0425");
301
+ console.log(hcpcs.data.short_description); // "Ground mileage, per statute mile"
302
+
303
+ // Look up a modifier
304
+ const mod = await client.hcpcs.lookupModifier("25");
305
+ console.log(mod.data.short_description);
306
+
307
+ // Batch lookup (up to 100)
308
+ const results = await client.hcpcs.lookupMany(["A0425", "E0100"]);
309
+
310
+ // Search
311
+ const results = await client.hcpcs.search({ q: "ambulance" });
312
+ ```
313
+
314
+ ### MS-DRG (Diagnosis Related Groups)
315
+
316
+ ```typescript
317
+ // Look up a DRG code
318
+ const drg = await client.msdrg.lookup("470");
319
+ console.log(drg.data.title); // "Major Joint Replacement..."
320
+
321
+ // Search
322
+ const results = await client.msdrg.search({
323
+ q: "cardiac",
324
+ type: "SURG",
325
+ });
326
+ ```
327
+
328
+ ### POS (Place of Service)
329
+
330
+ ```typescript
331
+ // Look up a POS code
332
+ const pos = await client.pos.lookup("11");
333
+ console.log(pos.data.name); // "Office"
334
+
335
+ // List all POS codes (~52 total)
336
+ const all = await client.pos.list();
337
+ ```
338
+
339
+ ### J-Code/NDC Crosswalk
340
+
341
+ ```typescript
342
+ // J-code → NDCs (which NDCs map to this J-code?)
343
+ const jcode = await client.jcode.byHcpcs("J9035");
344
+ console.log(`${jcode.data.ndc_count} NDCs for ${jcode.data.hcpcs_description}`);
345
+
346
+ // NDC → J-codes (which J-codes cover this NDC?)
347
+ const reverse = await client.jcode.byNdc("00004110002");
348
+ for (const entry of reverse.data.hcpcs_codes) {
349
+ console.log(`${entry.hcpcs_code}: ${entry.hcpcs_description}`);
350
+ }
351
+ ```
352
+
249
353
  ### Connectivity Intelligence
250
354
 
251
355
  Discover how to reach a provider's organization electronically — FHIR endpoints, Direct addresses, and more.
@@ -310,11 +414,11 @@ All lookup and search methods accept a `shape` option to control response detail
310
414
  const ndc = await client.ndc.lookup("0069-0151-01", { shape: "full" });
311
415
  ```
312
416
 
313
- **Exceptions**: SNOMED always returns full data (no shapes). FDA Labels lookup uses a metadata + sections model instead of shapes; search uses shapes.
417
+ **Exceptions**: SNOMED always returns full data (no shapes). FDA Labels lookup uses a metadata + sections model instead of shapes; search uses shapes. UCUM validate and convert return fixed result shapes (no shape parameter).
314
418
 
315
419
  ## Search
316
420
 
317
- All endpoints except Connectivity support full-text search with filters, facets, and pagination:
421
+ All endpoints except Connectivity and RxClass members support full-text search with filters, facets, and pagination:
318
422
 
319
423
  ```typescript
320
424
  const results = await client.ndc.search(
package/dist/index.cjs CHANGED
@@ -1590,6 +1590,302 @@ var DmdEndpoint = class {
1590
1590
  }
1591
1591
  };
1592
1592
 
1593
+ // src/endpoints/ucum.ts
1594
+ var UcumEndpoint = class {
1595
+ constructor(http) {
1596
+ this.http = http;
1597
+ }
1598
+ /**
1599
+ * Look up a single UCUM unit code.
1600
+ *
1601
+ * @param code - UCUM unit code (e.g., "mg", "kg/m2", "mmol/L")
1602
+ * @param options - Response shape and include options
1603
+ * @returns UCUM unit data
1604
+ *
1605
+ * @example
1606
+ * ```ts
1607
+ * const unit = await client.ucum.lookup("mg");
1608
+ * console.log(unit.data.display); // "milligram"
1609
+ * ```
1610
+ */
1611
+ async lookup(code, options) {
1612
+ return this.http.get(`/v1/ucum/${encodeURIComponent(code)}`, options);
1613
+ }
1614
+ /**
1615
+ * Look up multiple UCUM unit codes in a single request.
1616
+ *
1617
+ * @param codes - Array of UCUM unit codes (max 100)
1618
+ * @param options - Response shape, include, and batch options
1619
+ * @returns Batch response with results for each code
1620
+ */
1621
+ async lookupMany(codes, options) {
1622
+ if (codes.length === 0) throw new ValidationError("codes array must not be empty");
1623
+ if (codes.length > 100) throw new ValidationError(`UCUM batch lookup supports max 100 codes, got ${codes.length}`);
1624
+ return this.http.post(
1625
+ "/v1/ucum/_batch",
1626
+ { codes },
1627
+ options
1628
+ );
1629
+ }
1630
+ /**
1631
+ * Search for UCUM units.
1632
+ *
1633
+ * @param params - Search parameters (q, kind, property, metric, is_common_clinical)
1634
+ * @param options - Pagination and response shape options
1635
+ * @returns Search results with facets
1636
+ *
1637
+ * @example
1638
+ * ```ts
1639
+ * // Search for mass units
1640
+ * const results = await client.ucum.search({ q: "gram" });
1641
+ *
1642
+ * // Find common clinical units for length
1643
+ * const results = await client.ucum.search({
1644
+ * kind: "length",
1645
+ * is_common_clinical: true
1646
+ * });
1647
+ * ```
1648
+ */
1649
+ async search(params, options) {
1650
+ return this.http.search("/v1/ucum/search", {
1651
+ ...params,
1652
+ ...options,
1653
+ include: options?.include?.join(",")
1654
+ });
1655
+ }
1656
+ /**
1657
+ * Validate a UCUM expression.
1658
+ *
1659
+ * Checks whether a UCUM expression is syntactically valid and all
1660
+ * component unit codes are recognized.
1661
+ *
1662
+ * @param expression - UCUM expression to validate (e.g., "mg/dL", "kg.m-2")
1663
+ * @returns Validation result with component breakdown
1664
+ *
1665
+ * @example
1666
+ * ```ts
1667
+ * const result = await client.ucum.validate("mg/dL");
1668
+ * console.log(result.data.valid); // true
1669
+ *
1670
+ * const invalid = await client.ucum.validate("xyz123");
1671
+ * console.log(invalid.data.valid); // false
1672
+ * console.log(invalid.data.error); // description of the problem
1673
+ * ```
1674
+ */
1675
+ async validate(expression) {
1676
+ return this.http.get(
1677
+ `/v1/ucum/validate/${encodeURIComponent(expression)}`
1678
+ );
1679
+ }
1680
+ /**
1681
+ * Convert a value between UCUM units.
1682
+ *
1683
+ * Converts a numeric value from one UCUM unit to another compatible unit.
1684
+ * Both units must measure the same physical quantity (e.g., both mass,
1685
+ * both length).
1686
+ *
1687
+ * @param from - Source UCUM unit code
1688
+ * @param to - Target UCUM unit code
1689
+ * @param value - Numeric value to convert
1690
+ * @returns Conversion result with factor
1691
+ *
1692
+ * @example
1693
+ * ```ts
1694
+ * // Convert 5 kilograms to pounds
1695
+ * const result = await client.ucum.convert("kg", "[lb_av]", 5);
1696
+ * console.log(result.data.to.value); // ~11.0231
1697
+ *
1698
+ * // Convert temperature: 98.6 Fahrenheit to Celsius
1699
+ * const temp = await client.ucum.convert("[degF]", "Cel", 98.6);
1700
+ * console.log(temp.data.to.value); // 37
1701
+ * ```
1702
+ */
1703
+ async convert(from, to, value) {
1704
+ return this.http.search("/v1/ucum/convert", {
1705
+ from,
1706
+ to,
1707
+ value
1708
+ });
1709
+ }
1710
+ };
1711
+
1712
+ // src/endpoints/rxclass.ts
1713
+ var RxClassEndpoint = class {
1714
+ constructor(http) {
1715
+ this.http = http;
1716
+ }
1717
+ /**
1718
+ * Look up a single RxClass drug class.
1719
+ *
1720
+ * @param classId - RxClass identifier
1721
+ * @param options - Response shape and include options
1722
+ * @returns RxClass data
1723
+ *
1724
+ * @example
1725
+ * ```ts
1726
+ * const cls = await client.rxclass.lookup("N0000175557");
1727
+ * console.log(cls.data.class_name); // "HMG-CoA Reductase Inhibitors"
1728
+ * ```
1729
+ */
1730
+ async lookup(classId, options) {
1731
+ return this.http.get(`/v1/rxclass/${encodeURIComponent(classId)}`, options);
1732
+ }
1733
+ /**
1734
+ * Look up multiple RxClass drug classes in a single request.
1735
+ *
1736
+ * @param classIds - Array of RxClass identifiers (max 100)
1737
+ * @param options - Response shape, include, and batch options
1738
+ * @returns Batch response with results for each class ID
1739
+ */
1740
+ async lookupMany(classIds, options) {
1741
+ if (classIds.length === 0) throw new ValidationError("classIds array must not be empty");
1742
+ if (classIds.length > 100) throw new ValidationError(`RxClass batch lookup supports max 100 codes, got ${classIds.length}`);
1743
+ return this.http.post(
1744
+ "/v1/rxclass/_batch",
1745
+ { codes: classIds },
1746
+ options
1747
+ );
1748
+ }
1749
+ /**
1750
+ * Search for drug classes.
1751
+ *
1752
+ * @param params - Search parameters (q, class_type)
1753
+ * @param options - Pagination and response shape options
1754
+ * @returns Search results with facets
1755
+ *
1756
+ * @example
1757
+ * ```ts
1758
+ * // Search for statin-related classes
1759
+ * const results = await client.rxclass.search({ q: "statin" });
1760
+ *
1761
+ * // Find all EPC (Established Pharmacologic Class) entries
1762
+ * const results = await client.rxclass.search({
1763
+ * class_type: "EPC"
1764
+ * });
1765
+ * ```
1766
+ */
1767
+ async search(params, options) {
1768
+ return this.http.search("/v1/rxclass/search", {
1769
+ ...params,
1770
+ ...options,
1771
+ include: options?.include?.join(",")
1772
+ });
1773
+ }
1774
+ /**
1775
+ * Get member drugs of a drug class.
1776
+ *
1777
+ * Returns the list of RxNorm concepts (RxCUIs) that belong to the
1778
+ * specified drug class.
1779
+ *
1780
+ * @param classId - RxClass identifier
1781
+ * @param options - Response shape and include options
1782
+ * @returns Members response with array of RxCUI members
1783
+ *
1784
+ * @example
1785
+ * ```ts
1786
+ * // Get all drugs in a class
1787
+ * const members = await client.rxclass.members("N0000175557");
1788
+ * console.log(members.data.count); // number of member drugs
1789
+ * console.log(members.data.members); // [{ rxcui: "...", name: "..." }, ...]
1790
+ * ```
1791
+ */
1792
+ async members(classId, options) {
1793
+ return this.http.get(
1794
+ `/v1/rxclass/${encodeURIComponent(classId)}/members`,
1795
+ options
1796
+ );
1797
+ }
1798
+ };
1799
+
1800
+ // src/endpoints/hcpcs.ts
1801
+ var HcpcsEndpoint = class {
1802
+ constructor(http) {
1803
+ this.http = http;
1804
+ }
1805
+ async lookup(code, options) {
1806
+ return this.http.get(`/v1/hcpcs/${encodeURIComponent(code)}`, options);
1807
+ }
1808
+ async lookupModifier(code, options) {
1809
+ return this.http.get(`/v1/hcpcs/modifier/${encodeURIComponent(code)}`, options);
1810
+ }
1811
+ async lookupMany(codes, options) {
1812
+ if (codes.length === 0) throw new ValidationError("codes array must not be empty");
1813
+ if (codes.length > 100) throw new ValidationError(`HCPCS batch lookup supports max 100 codes, got ${codes.length}`);
1814
+ return this.http.post("/v1/hcpcs/_batch", { codes }, options);
1815
+ }
1816
+ async search(params, options) {
1817
+ return this.http.search("/v1/hcpcs/search", {
1818
+ ...params,
1819
+ ...options,
1820
+ include: options?.include?.join(",")
1821
+ });
1822
+ }
1823
+ };
1824
+
1825
+ // src/endpoints/msdrg.ts
1826
+ var MsdrgEndpoint = class {
1827
+ constructor(http) {
1828
+ this.http = http;
1829
+ }
1830
+ async lookup(code, options) {
1831
+ return this.http.get(`/v1/msdrg/${encodeURIComponent(code)}`, options);
1832
+ }
1833
+ async lookupMany(codes, options) {
1834
+ if (codes.length === 0) throw new ValidationError("codes array must not be empty");
1835
+ if (codes.length > 100) throw new ValidationError(`MS-DRG batch lookup supports max 100 codes, got ${codes.length}`);
1836
+ return this.http.post("/v1/msdrg/_batch", { codes }, options);
1837
+ }
1838
+ async search(params, options) {
1839
+ return this.http.search("/v1/msdrg/search", {
1840
+ ...params,
1841
+ ...options,
1842
+ include: options?.include?.join(",")
1843
+ });
1844
+ }
1845
+ };
1846
+
1847
+ // src/endpoints/pos.ts
1848
+ var PosEndpoint = class {
1849
+ constructor(http) {
1850
+ this.http = http;
1851
+ }
1852
+ async lookup(code, options) {
1853
+ return this.http.get(`/v1/pos/${encodeURIComponent(code)}`, options);
1854
+ }
1855
+ async lookupMany(codes, options) {
1856
+ if (codes.length === 0) throw new ValidationError("codes array must not be empty");
1857
+ if (codes.length > 100) throw new ValidationError(`POS batch lookup supports max 100 codes, got ${codes.length}`);
1858
+ return this.http.post("/v1/pos/_batch", { codes }, options);
1859
+ }
1860
+ /**
1861
+ * List all Place of Service codes (~52 codes).
1862
+ */
1863
+ async list(options) {
1864
+ return this.http.get("/v1/pos/list", options);
1865
+ }
1866
+ };
1867
+
1868
+ // src/endpoints/jcode.ts
1869
+ var JcodeEndpoint = class {
1870
+ constructor(http) {
1871
+ this.http = http;
1872
+ }
1873
+ /**
1874
+ * Look up NDC codes for a HCPCS J-code.
1875
+ * @param code - HCPCS code (J, Q, A, C codes or 5-digit numeric)
1876
+ */
1877
+ async byHcpcs(code) {
1878
+ return this.http.get(`/v1/jcode/by-hcpcs/${encodeURIComponent(code)}`);
1879
+ }
1880
+ /**
1881
+ * Reverse lookup: find HCPCS codes for an NDC.
1882
+ * @param ndc - NDC code (11 digits, with or without dashes)
1883
+ */
1884
+ async byNdc(ndc) {
1885
+ return this.http.get(`/v1/jcode/by-ndc/${encodeURIComponent(ndc)}`);
1886
+ }
1887
+ };
1888
+
1593
1889
  // src/client.ts
1594
1890
  var Fhirfly = class {
1595
1891
  http;
@@ -1660,6 +1956,36 @@ var Fhirfly = class {
1660
1956
  * UK NHS medicines reference data standard covering VTM/VMP/AMP/VMPP/AMPP.
1661
1957
  */
1662
1958
  dmd;
1959
+ /**
1960
+ * UCUM (Unified Code for Units of Measure) lookups.
1961
+ * Standardized units of measure for healthcare and science, with validation and conversion.
1962
+ */
1963
+ ucum;
1964
+ /**
1965
+ * RxClass drug classification hierarchy lookups.
1966
+ * ATC, EPC, MOA, PE, and CHEM drug class types with member drug listings.
1967
+ */
1968
+ rxclass;
1969
+ /**
1970
+ * HCPCS Level II procedure and supply code lookups.
1971
+ * CMS codes for non-physician services, supplies, and equipment.
1972
+ */
1973
+ hcpcs;
1974
+ /**
1975
+ * MS-DRG (Medicare Severity Diagnosis Related Group) lookups.
1976
+ * Inpatient hospital payment classifications with weights and length of stay.
1977
+ */
1978
+ msdrg;
1979
+ /**
1980
+ * Place of Service code lookups.
1981
+ * CMS codes identifying where healthcare services were rendered.
1982
+ */
1983
+ pos;
1984
+ /**
1985
+ * J-Code/NDC crosswalk lookups.
1986
+ * Bidirectional mapping between HCPCS J-codes and NDC drug codes.
1987
+ */
1988
+ jcode;
1663
1989
  /**
1664
1990
  * Create a new FHIRfly client.
1665
1991
  *
@@ -1712,6 +2038,12 @@ var Fhirfly = class {
1712
2038
  this.hcc = new HccEndpoint(this.http);
1713
2039
  this.opcs4 = new Opcs4Endpoint(this.http);
1714
2040
  this.dmd = new DmdEndpoint(this.http);
2041
+ this.ucum = new UcumEndpoint(this.http);
2042
+ this.rxclass = new RxClassEndpoint(this.http);
2043
+ this.hcpcs = new HcpcsEndpoint(this.http);
2044
+ this.msdrg = new MsdrgEndpoint(this.http);
2045
+ this.pos = new PosEndpoint(this.http);
2046
+ this.jcode = new JcodeEndpoint(this.http);
1715
2047
  }
1716
2048
  };
1717
2049
 
@@ -1721,14 +2053,20 @@ exports.DmdEndpoint = DmdEndpoint;
1721
2053
  exports.Fhirfly = Fhirfly;
1722
2054
  exports.FhirflyError = FhirflyError;
1723
2055
  exports.HccEndpoint = HccEndpoint;
2056
+ exports.HcpcsEndpoint = HcpcsEndpoint;
2057
+ exports.JcodeEndpoint = JcodeEndpoint;
2058
+ exports.MsdrgEndpoint = MsdrgEndpoint;
1724
2059
  exports.NetworkError = NetworkError;
1725
2060
  exports.NotFoundError = NotFoundError;
1726
2061
  exports.Opcs4Endpoint = Opcs4Endpoint;
2062
+ exports.PosEndpoint = PosEndpoint;
1727
2063
  exports.QuotaExceededError = QuotaExceededError;
1728
2064
  exports.RateLimitError = RateLimitError;
2065
+ exports.RxClassEndpoint = RxClassEndpoint;
1729
2066
  exports.ServerError = ServerError;
1730
2067
  exports.TimeoutError = TimeoutError;
1731
2068
  exports.TokenManager = TokenManager;
2069
+ exports.UcumEndpoint = UcumEndpoint;
1732
2070
  exports.ValidationError = ValidationError;
1733
2071
  //# sourceMappingURL=index.cjs.map
1734
2072
  //# sourceMappingURL=index.cjs.map