autoicd-js 0.5.1 → 0.7.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/dist/index.js CHANGED
@@ -69,9 +69,13 @@ var AutoICD = class {
69
69
  /** Rate limit info from the most recent API response. */
70
70
  lastRateLimit = null;
71
71
  /** Sub-resource for ICD-10 code lookup. */
72
- codes;
72
+ icd10;
73
73
  /** Sub-resource for ICD-11 code lookup. */
74
74
  icd11;
75
+ /** Sub-resource for ICF code lookup and coding. */
76
+ icf;
77
+ /** Sub-resource for LOINC code lookup and coding. */
78
+ loinc;
75
79
  constructor(options) {
76
80
  if (!options.apiKey) {
77
81
  throw new Error("apiKey is required");
@@ -80,8 +84,10 @@ var AutoICD = class {
80
84
  this.baseURL = (options.baseURL ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
81
85
  this.timeout = options.timeout ?? DEFAULT_TIMEOUT;
82
86
  this._fetch = options.fetch ?? globalThis.fetch;
83
- this.codes = new Codes(this);
87
+ this.icd10 = new ICD10Codes(this);
84
88
  this.icd11 = new ICD11Codes(this);
89
+ this.icf = new ICFCodes(this);
90
+ this.loinc = new LOINCCodes(this);
85
91
  }
86
92
  // ─── Public Methods ───
87
93
  /**
@@ -100,7 +106,11 @@ var AutoICD = class {
100
106
  text,
101
107
  top_k: options?.topK,
102
108
  include_negated: options?.includeNegated,
103
- output_system: options?.outputSystem
109
+ output_system: options?.outputSystem,
110
+ include_icf: options?.includeIcf,
111
+ include_icd11: options?.includeIcd11,
112
+ include_snomed: options?.includeSnomed,
113
+ include_umls: options?.includeUmls
104
114
  });
105
115
  }
106
116
  /**
@@ -116,6 +126,27 @@ var AutoICD = class {
116
126
  async anonymize(text) {
117
127
  return this.post("/api/v1/anonymize", { text });
118
128
  }
129
+ /**
130
+ * Audit a chart for coding gaps, RADV risk, specificity, denial flags, and
131
+ * a reconciled problem list. Every finding carries extractive evidence spans.
132
+ *
133
+ * @example
134
+ * ```ts
135
+ * const audit = await autoicd.audit({
136
+ * text: "68yo M, type 2 diabetes, chronic systolic heart failure on furosemide.",
137
+ * codes: [{ code: "E11.9", kind: "icd10" }],
138
+ * capabilities: ["hcc", "radv", "specificity", "denial", "problem_list"],
139
+ * context: { patient: { coverage: "medicare_advantage" } },
140
+ * });
141
+ * console.log(audit.totals.estimated_revenue_recovery);
142
+ * for (const m of audit.missed) {
143
+ * console.log(`${m.code} ${m.hcc_category} $${m.estimated_revenue}`);
144
+ * }
145
+ * ```
146
+ */
147
+ async audit(request) {
148
+ return this.post("/api/v1/audit", request);
149
+ }
119
150
  // ─── Internal HTTP ───
120
151
  /** @internal */
121
152
  async get(path) {
@@ -173,7 +204,7 @@ var AutoICD = class {
173
204
  }
174
205
  }
175
206
  };
176
- var Codes = class {
207
+ var ICD10Codes = class {
177
208
  constructor(client) {
178
209
  this.client = client;
179
210
  }
@@ -182,14 +213,14 @@ var Codes = class {
182
213
  *
183
214
  * @example
184
215
  * ```ts
185
- * const results = await autoicd.codes.search("diabetes mellitus");
216
+ * const results = await autoicd.icd10.search("diabetes mellitus");
186
217
  * ```
187
218
  */
188
219
  async search(query, options) {
189
220
  const params = new URLSearchParams({ q: query });
190
221
  if (options?.limit !== void 0) params.set("limit", String(options.limit));
191
222
  if (options?.offset !== void 0) params.set("offset", String(options.offset));
192
- return this.client.get(`/api/v1/codes/search?${params}`);
223
+ return this.client.get(`/api/v1/icd10/codes/search?${params}`);
193
224
  }
194
225
  /**
195
226
  * Get comprehensive details for a single ICD-10 code, including synonyms,
@@ -197,7 +228,7 @@ var Codes = class {
197
228
  *
198
229
  * @example
199
230
  * ```ts
200
- * const detail = await autoicd.codes.get("E11.9");
231
+ * const detail = await autoicd.icd10.get("E11.9");
201
232
  * console.log(detail.long_description);
202
233
  * console.log(detail.synonyms.snomed); // SNOMED CT synonyms
203
234
  * console.log(detail.chapter?.title); // "Endocrine, Nutritional and Metabolic Diseases"
@@ -205,7 +236,7 @@ var Codes = class {
205
236
  * ```
206
237
  */
207
238
  async get(code) {
208
- return this.client.get(`/api/v1/codes/${encodeURIComponent(code)}`);
239
+ return this.client.get(`/api/v1/icd10/codes/${encodeURIComponent(code)}`);
209
240
  }
210
241
  };
211
242
  var ICD11Codes = class {
@@ -242,6 +273,124 @@ var ICD11Codes = class {
242
273
  return this.client.get(`/api/v1/icd11/codes/${encodeURIComponent(code)}`);
243
274
  }
244
275
  };
276
+ var ICFCodes = class {
277
+ constructor(client) {
278
+ this.client = client;
279
+ }
280
+ /**
281
+ * Code clinical text to ICF codes.
282
+ *
283
+ * @example
284
+ * ```ts
285
+ * const result = await autoicd.icf.code("Patient has difficulty walking");
286
+ * for (const entity of result.results) {
287
+ * console.log(entity.entity_text, entity.codes[0]?.code);
288
+ * }
289
+ * ```
290
+ */
291
+ async code(text, options) {
292
+ return this.client.post("/api/v1/icf/code", {
293
+ text,
294
+ top_k: options?.topK
295
+ });
296
+ }
297
+ /**
298
+ * Get full details for a single ICF code, including definition,
299
+ * hierarchy (parent/children), inclusions, exclusions, and index terms.
300
+ *
301
+ * @example
302
+ * ```ts
303
+ * const detail = await autoicd.icf.lookup("b280");
304
+ * console.log(detail.title);
305
+ * console.log(detail.definition);
306
+ * console.log(detail.children.length);
307
+ * ```
308
+ */
309
+ async lookup(code) {
310
+ return this.client.get(`/api/v1/icf/codes/${encodeURIComponent(code)}`);
311
+ }
312
+ /**
313
+ * Search ICF codes by description.
314
+ *
315
+ * @example
316
+ * ```ts
317
+ * const results = await autoicd.icf.search("pain");
318
+ * ```
319
+ */
320
+ async search(query, options) {
321
+ const params = new URLSearchParams({ q: query });
322
+ if (options?.limit !== void 0) params.set("limit", String(options.limit));
323
+ if (options?.offset !== void 0) params.set("offset", String(options.offset));
324
+ return this.client.get(`/api/v1/icf/codes/search?${params}`);
325
+ }
326
+ /**
327
+ * Get the ICF Core Set for an ICD-10 diagnosis code.
328
+ *
329
+ * @example
330
+ * ```ts
331
+ * const coreSet = await autoicd.icf.coreSet("M54.5");
332
+ * console.log(coreSet.condition_name);
333
+ * console.log(coreSet.brief.length, "brief codes");
334
+ * console.log(coreSet.comprehensive.length, "comprehensive codes");
335
+ * ```
336
+ */
337
+ async coreSet(icd10Code) {
338
+ return this.client.get(`/api/v1/icf/core-set/${encodeURIComponent(icd10Code)}`);
339
+ }
340
+ };
341
+ var LOINCCodes = class {
342
+ constructor(client) {
343
+ this.client = client;
344
+ }
345
+ /**
346
+ * Code clinical text to LOINC codes.
347
+ *
348
+ * Extracts lab tests, imaging orders, and clinical observations from
349
+ * free text and matches to LOINC codes using NER + SapBERT embeddings.
350
+ *
351
+ * @example
352
+ * ```ts
353
+ * const result = await autoicd.loinc.code("Order CBC, glucose, and TSH");
354
+ * for (const entity of result.results) {
355
+ * console.log(entity.entity_text, entity.codes[0]?.code);
356
+ * }
357
+ * ```
358
+ */
359
+ async code(text, options) {
360
+ return this.client.post("/api/v1/loinc/code", {
361
+ text,
362
+ top_k: options?.topK
363
+ });
364
+ }
365
+ /**
366
+ * Get full details for a single LOINC code, including 6-axis classification,
367
+ * definition, related names, and cross-references.
368
+ *
369
+ * @example
370
+ * ```ts
371
+ * const detail = await autoicd.loinc.lookup("2345-7");
372
+ * console.log(detail.long_common_name);
373
+ * console.log(detail.component, detail.system);
374
+ * ```
375
+ */
376
+ async lookup(code) {
377
+ return this.client.get(`/api/v1/loinc/codes/${encodeURIComponent(code)}`);
378
+ }
379
+ /**
380
+ * Search LOINC codes by description.
381
+ *
382
+ * @example
383
+ * ```ts
384
+ * const results = await autoicd.loinc.search("glucose");
385
+ * ```
386
+ */
387
+ async search(query, options) {
388
+ const params = new URLSearchParams({ q: query });
389
+ if (options?.limit !== void 0) params.set("limit", String(options.limit));
390
+ if (options?.offset !== void 0) params.set("offset", String(options.offset));
391
+ return this.client.get(`/api/v1/loinc/codes/search?${params}`);
392
+ }
393
+ };
245
394
  function parseRateLimit(headers) {
246
395
  const limit = headers.get("X-RateLimit-Limit");
247
396
  const remaining = headers.get("X-RateLimit-Remaining");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/client.ts"],"sourcesContent":["export { AutoICD } from \"./client.js\";\n\nexport type {\n AutoICDOptions,\n CodeOptions,\n CodeMatch,\n CodingEntity,\n CodingResponse,\n SearchOptions,\n CodeDetail,\n CodeDetailFull,\n ChapterInfo,\n CodeSearchResponse,\n PIIEntity,\n AnonymizeResponse,\n RateLimit,\n ICD11CodeDetail,\n ICD11ChapterInfo,\n CrosswalkMapping,\n ICD11CodeDetailFull,\n ICD11CodeSearchResult,\n ICD11CodeSearchResponse,\n} from \"./types.js\";\n\nexport {\n AutoICDError,\n AuthenticationError,\n RateLimitError,\n NotFoundError,\n} from \"./errors.js\";\n","import type { RateLimit } from \"./types.js\";\n\nexport class AutoICDError extends Error {\n readonly status: number;\n\n constructor(status: number, message: string) {\n super(message);\n this.name = \"AutoICDError\";\n this.status = status;\n }\n}\n\nexport class AuthenticationError extends AutoICDError {\n constructor(message = \"Invalid API key\") {\n super(401, message);\n this.name = \"AuthenticationError\";\n }\n}\n\nexport class RateLimitError extends AutoICDError {\n readonly rateLimit: RateLimit;\n\n constructor(message: string, rateLimit: RateLimit) {\n super(429, message);\n this.name = \"RateLimitError\";\n this.rateLimit = rateLimit;\n }\n}\n\nexport class NotFoundError extends AutoICDError {\n constructor(message = \"Resource not found\") {\n super(404, message);\n this.name = \"NotFoundError\";\n }\n}\n","import type {\n AutoICDOptions,\n CodeOptions,\n CodingResponse,\n SearchOptions,\n CodeSearchResponse,\n CodeDetail,\n CodeDetailFull,\n AnonymizeResponse,\n RateLimit,\n ErrorBody,\n ICD11CodeSearchResponse,\n ICD11CodeDetailFull,\n} from \"./types.js\";\nimport {\n AutoICDError,\n AuthenticationError,\n RateLimitError,\n NotFoundError,\n} from \"./errors.js\";\n\nconst DEFAULT_BASE_URL = \"https://autoicdapi.com\";\nconst DEFAULT_TIMEOUT = 30_000;\n\nexport class AutoICD {\n private readonly apiKey: string;\n private readonly baseURL: string;\n private readonly timeout: number;\n private readonly _fetch: typeof globalThis.fetch;\n\n /** Rate limit info from the most recent API response. */\n lastRateLimit: RateLimit | null = null;\n\n /** Sub-resource for ICD-10 code lookup. */\n readonly codes: Codes;\n\n /** Sub-resource for ICD-11 code lookup. */\n readonly icd11: ICD11Codes;\n\n constructor(options: AutoICDOptions) {\n if (!options.apiKey) {\n throw new Error(\"apiKey is required\");\n }\n this.apiKey = options.apiKey;\n this.baseURL = (options.baseURL ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n this._fetch = options.fetch ?? globalThis.fetch;\n this.codes = new Codes(this);\n this.icd11 = new ICD11Codes(this);\n }\n\n // ─── Public Methods ───\n\n /**\n * Code clinical text to ICD-10-CM diagnoses.\n *\n * @example\n * ```ts\n * const result = await autoicd.code(\"Patient has type 2 diabetes\");\n * for (const entity of result.entities) {\n * console.log(entity.entity_text, entity.codes[0]?.code);\n * }\n * ```\n */\n async code(text: string, options?: CodeOptions): Promise<CodingResponse> {\n return this.post<CodingResponse>(\"/api/v1/code\", {\n text,\n top_k: options?.topK,\n include_negated: options?.includeNegated,\n output_system: options?.outputSystem,\n });\n }\n\n /**\n * Anonymize PHI/PII in clinical text.\n *\n * @example\n * ```ts\n * const result = await autoicd.anonymize(\"John Smith, DOB 01/15/1980, has COPD\");\n * console.log(result.anonymized_text);\n * // \"[NAME], DOB [DATE], has COPD\"\n * ```\n */\n async anonymize(text: string): Promise<AnonymizeResponse> {\n return this.post<AnonymizeResponse>(\"/api/v1/anonymize\", { text });\n }\n\n // ─── Internal HTTP ───\n\n /** @internal */\n async get<T>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n /** @internal */\n async post<T>(path: string, body: Record<string, unknown>): Promise<T> {\n // Strip undefined values so the API receives clean JSON\n const clean = Object.fromEntries(\n Object.entries(body).filter(([, v]) => v !== undefined)\n );\n return this.request<T>(\"POST\", path, clean);\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: Record<string, unknown>\n ): Promise<T> {\n const url = `${this.baseURL}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const res = await this._fetch(url, {\n method,\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n // Parse rate limit headers\n this.lastRateLimit = parseRateLimit(res.headers);\n\n if (res.ok) {\n return (await res.json()) as T;\n }\n\n // Error responses\n const errorBody = (await res.json().catch(() => null)) as ErrorBody | null;\n const message = errorBody?.error ?? `HTTP ${res.status}`;\n\n if (res.status === 401) throw new AuthenticationError(message);\n if (res.status === 404) throw new NotFoundError(message);\n if (res.status === 429) {\n throw new RateLimitError(\n message,\n this.lastRateLimit ?? {\n limit: errorBody?.limit ?? 0,\n remaining: 0,\n resetAt: errorBody?.resetAt ? new Date(errorBody.resetAt) : new Date(),\n }\n );\n }\n\n throw new AutoICDError(res.status, message);\n } catch (err) {\n if (err instanceof AutoICDError) throw err;\n if (err instanceof DOMException && err.name === \"AbortError\") {\n throw new AutoICDError(0, `Request timed out after ${this.timeout}ms`);\n }\n throw err;\n } finally {\n clearTimeout(timer);\n }\n }\n}\n\n// ─── Codes Sub-resource ───\n\nclass Codes {\n constructor(private readonly client: AutoICD) {}\n\n /**\n * Search ICD-10 codes by description.\n *\n * @example\n * ```ts\n * const results = await autoicd.codes.search(\"diabetes mellitus\");\n * ```\n */\n async search(query: string, options?: SearchOptions): Promise<CodeSearchResponse> {\n const params = new URLSearchParams({ q: query });\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options?.offset !== undefined) params.set(\"offset\", String(options.offset));\n return this.client.get<CodeSearchResponse>(`/api/v1/codes/search?${params}`);\n }\n\n /**\n * Get comprehensive details for a single ICD-10 code, including synonyms,\n * hierarchy (parent/children), chapter, and SNOMED CT / UMLS cross-references.\n *\n * @example\n * ```ts\n * const detail = await autoicd.codes.get(\"E11.9\");\n * console.log(detail.long_description);\n * console.log(detail.synonyms.snomed); // SNOMED CT synonyms\n * console.log(detail.chapter?.title); // \"Endocrine, Nutritional and Metabolic Diseases\"\n * console.log(detail.children.length); // child codes\n * ```\n */\n async get(code: string): Promise<CodeDetailFull> {\n return this.client.get<CodeDetailFull>(`/api/v1/codes/${encodeURIComponent(code)}`);\n }\n\n}\n\n// ─── ICD-11 Codes Sub-resource ───\n\nclass ICD11Codes {\n constructor(private readonly client: AutoICD) {}\n\n /**\n * Search ICD-11 codes by description.\n *\n * @example\n * ```ts\n * const results = await autoicd.icd11.search(\"diabetes mellitus\");\n * ```\n */\n async search(query: string, options?: SearchOptions): Promise<ICD11CodeSearchResponse> {\n const params = new URLSearchParams({ q: query });\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options?.offset !== undefined) params.set(\"offset\", String(options.offset));\n return this.client.get<ICD11CodeSearchResponse>(`/api/v1/icd11/codes/search?${params}`);\n }\n\n /**\n * Get comprehensive details for a single ICD-11 code, including synonyms,\n * hierarchy (parent/children), chapter, and ICD-10 crosswalk mappings.\n *\n * @example\n * ```ts\n * const detail = await autoicd.icd11.get(\"5A11\");\n * console.log(detail.long_description);\n * console.log(detail.chapter?.title);\n * console.log(detail.icd10_mappings);\n * ```\n */\n async get(code: string): Promise<ICD11CodeDetailFull> {\n return this.client.get<ICD11CodeDetailFull>(`/api/v1/icd11/codes/${encodeURIComponent(code)}`);\n }\n}\n\n// ─── Helpers ───\n\nfunction parseRateLimit(headers: Headers): RateLimit | null {\n const limit = headers.get(\"X-RateLimit-Limit\");\n const remaining = headers.get(\"X-RateLimit-Remaining\");\n const reset = headers.get(\"X-RateLimit-Reset\");\n\n if (!limit || !remaining || !reset) return null;\n\n return {\n limit: parseInt(limit, 10),\n remaining: parseInt(remaining, 10),\n resetAt: new Date(reset),\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/client.ts"],"sourcesContent":["export { AutoICD } from \"./client.js\";\n\nexport type {\n AutoICDOptions,\n CodeOptions,\n CodeMatch,\n CodingEntity,\n CodingResponse,\n SearchOptions,\n CodeDetail,\n CodeDetailFull,\n ChapterInfo,\n CodeSearchResponse,\n PIIEntity,\n AnonymizeResponse,\n RateLimit,\n ICD11CodeDetail,\n ICD11ChapterInfo,\n CrosswalkMapping,\n ICD11CodeDetailFull,\n ICD11CodeSearchResult,\n ICD11CodeSearchResponse,\n ICFComponent,\n ICFCodeSummary,\n ICFCodeDetail,\n ICFCodeResult,\n ICFCodingEntity,\n ICFCodingResponse,\n ICFSearchResponse,\n ICFCoreSetResult,\n ICFCrossReference,\n LOINCCodeSummary,\n LOINCCodeDetail,\n LOINCSearchResponse,\n LOINCCodeResult,\n LOINCCodingEntity,\n LOINCCodingResponse,\n AuditCapability,\n AuditCode,\n AuditDocument,\n AuditContext,\n AuditRequest,\n AuditResponse,\n EvidenceSpan,\n ConfirmedCode,\n MissedCode,\n UnsupportedCode,\n SpecificityUpgrade,\n DenialRisk,\n ProblemListEntry,\n AuditTotals,\n RatesUsed,\n UpgradeHint,\n} from \"./types.js\";\n\nexport {\n AutoICDError,\n AuthenticationError,\n RateLimitError,\n NotFoundError,\n} from \"./errors.js\";\n","import type { RateLimit } from \"./types.js\";\n\nexport class AutoICDError extends Error {\n readonly status: number;\n\n constructor(status: number, message: string) {\n super(message);\n this.name = \"AutoICDError\";\n this.status = status;\n }\n}\n\nexport class AuthenticationError extends AutoICDError {\n constructor(message = \"Invalid API key\") {\n super(401, message);\n this.name = \"AuthenticationError\";\n }\n}\n\nexport class RateLimitError extends AutoICDError {\n readonly rateLimit: RateLimit;\n\n constructor(message: string, rateLimit: RateLimit) {\n super(429, message);\n this.name = \"RateLimitError\";\n this.rateLimit = rateLimit;\n }\n}\n\nexport class NotFoundError extends AutoICDError {\n constructor(message = \"Resource not found\") {\n super(404, message);\n this.name = \"NotFoundError\";\n }\n}\n","import type {\n AutoICDOptions,\n CodeOptions,\n CodingResponse,\n SearchOptions,\n CodeSearchResponse,\n CodeDetail,\n CodeDetailFull,\n AnonymizeResponse,\n RateLimit,\n ErrorBody,\n ICD11CodeSearchResponse,\n ICD11CodeDetailFull,\n ICFCodingResponse,\n ICFCodeDetail,\n ICFSearchResponse,\n ICFCoreSetResult,\n LOINCCodeDetail,\n LOINCSearchResponse,\n LOINCCodingResponse,\n AuditRequest,\n AuditResponse,\n} from \"./types.js\";\nimport {\n AutoICDError,\n AuthenticationError,\n RateLimitError,\n NotFoundError,\n} from \"./errors.js\";\n\nconst DEFAULT_BASE_URL = \"https://autoicdapi.com\";\nconst DEFAULT_TIMEOUT = 30_000;\n\nexport class AutoICD {\n private readonly apiKey: string;\n private readonly baseURL: string;\n private readonly timeout: number;\n private readonly _fetch: typeof globalThis.fetch;\n\n /** Rate limit info from the most recent API response. */\n lastRateLimit: RateLimit | null = null;\n\n /** Sub-resource for ICD-10 code lookup. */\n readonly icd10: ICD10Codes;\n\n /** Sub-resource for ICD-11 code lookup. */\n readonly icd11: ICD11Codes;\n\n /** Sub-resource for ICF code lookup and coding. */\n readonly icf: ICFCodes;\n\n /** Sub-resource for LOINC code lookup and coding. */\n readonly loinc: LOINCCodes;\n\n constructor(options: AutoICDOptions) {\n if (!options.apiKey) {\n throw new Error(\"apiKey is required\");\n }\n this.apiKey = options.apiKey;\n this.baseURL = (options.baseURL ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n this._fetch = options.fetch ?? globalThis.fetch;\n this.icd10 = new ICD10Codes(this);\n this.icd11 = new ICD11Codes(this);\n this.icf = new ICFCodes(this);\n this.loinc = new LOINCCodes(this);\n }\n\n // ─── Public Methods ───\n\n /**\n * Code clinical text to ICD-10-CM diagnoses.\n *\n * @example\n * ```ts\n * const result = await autoicd.code(\"Patient has type 2 diabetes\");\n * for (const entity of result.entities) {\n * console.log(entity.entity_text, entity.codes[0]?.code);\n * }\n * ```\n */\n async code(text: string, options?: CodeOptions): Promise<CodingResponse> {\n return this.post<CodingResponse>(\"/api/v1/code\", {\n text,\n top_k: options?.topK,\n include_negated: options?.includeNegated,\n output_system: options?.outputSystem,\n include_icf: options?.includeIcf,\n include_icd11: options?.includeIcd11,\n include_snomed: options?.includeSnomed,\n include_umls: options?.includeUmls,\n });\n }\n\n /**\n * Anonymize PHI/PII in clinical text.\n *\n * @example\n * ```ts\n * const result = await autoicd.anonymize(\"John Smith, DOB 01/15/1980, has COPD\");\n * console.log(result.anonymized_text);\n * // \"[NAME], DOB [DATE], has COPD\"\n * ```\n */\n async anonymize(text: string): Promise<AnonymizeResponse> {\n return this.post<AnonymizeResponse>(\"/api/v1/anonymize\", { text });\n }\n\n /**\n * Audit a chart for coding gaps, RADV risk, specificity, denial flags, and\n * a reconciled problem list. Every finding carries extractive evidence spans.\n *\n * @example\n * ```ts\n * const audit = await autoicd.audit({\n * text: \"68yo M, type 2 diabetes, chronic systolic heart failure on furosemide.\",\n * codes: [{ code: \"E11.9\", kind: \"icd10\" }],\n * capabilities: [\"hcc\", \"radv\", \"specificity\", \"denial\", \"problem_list\"],\n * context: { patient: { coverage: \"medicare_advantage\" } },\n * });\n * console.log(audit.totals.estimated_revenue_recovery);\n * for (const m of audit.missed) {\n * console.log(`${m.code} ${m.hcc_category} $${m.estimated_revenue}`);\n * }\n * ```\n */\n async audit(request: AuditRequest): Promise<AuditResponse> {\n return this.post<AuditResponse>(\"/api/v1/audit\", request as unknown as Record<string, unknown>);\n }\n\n // ─── Internal HTTP ───\n\n /** @internal */\n async get<T>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n /** @internal */\n async post<T>(path: string, body: Record<string, unknown>): Promise<T> {\n // Strip undefined values so the API receives clean JSON\n const clean = Object.fromEntries(\n Object.entries(body).filter(([, v]) => v !== undefined)\n );\n return this.request<T>(\"POST\", path, clean);\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: Record<string, unknown>\n ): Promise<T> {\n const url = `${this.baseURL}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const res = await this._fetch(url, {\n method,\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n // Parse rate limit headers\n this.lastRateLimit = parseRateLimit(res.headers);\n\n if (res.ok) {\n return (await res.json()) as T;\n }\n\n // Error responses\n const errorBody = (await res.json().catch(() => null)) as ErrorBody | null;\n const message = errorBody?.error ?? `HTTP ${res.status}`;\n\n if (res.status === 401) throw new AuthenticationError(message);\n if (res.status === 404) throw new NotFoundError(message);\n if (res.status === 429) {\n throw new RateLimitError(\n message,\n this.lastRateLimit ?? {\n limit: errorBody?.limit ?? 0,\n remaining: 0,\n resetAt: errorBody?.resetAt ? new Date(errorBody.resetAt) : new Date(),\n }\n );\n }\n\n throw new AutoICDError(res.status, message);\n } catch (err) {\n if (err instanceof AutoICDError) throw err;\n if (err instanceof DOMException && err.name === \"AbortError\") {\n throw new AutoICDError(0, `Request timed out after ${this.timeout}ms`);\n }\n throw err;\n } finally {\n clearTimeout(timer);\n }\n }\n}\n\n// ─── ICD-10 Codes Sub-resource ───\n\nclass ICD10Codes {\n constructor(private readonly client: AutoICD) {}\n\n /**\n * Search ICD-10 codes by description.\n *\n * @example\n * ```ts\n * const results = await autoicd.icd10.search(\"diabetes mellitus\");\n * ```\n */\n async search(query: string, options?: SearchOptions): Promise<CodeSearchResponse> {\n const params = new URLSearchParams({ q: query });\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options?.offset !== undefined) params.set(\"offset\", String(options.offset));\n return this.client.get<CodeSearchResponse>(`/api/v1/icd10/codes/search?${params}`);\n }\n\n /**\n * Get comprehensive details for a single ICD-10 code, including synonyms,\n * hierarchy (parent/children), chapter, and SNOMED CT / UMLS cross-references.\n *\n * @example\n * ```ts\n * const detail = await autoicd.icd10.get(\"E11.9\");\n * console.log(detail.long_description);\n * console.log(detail.synonyms.snomed); // SNOMED CT synonyms\n * console.log(detail.chapter?.title); // \"Endocrine, Nutritional and Metabolic Diseases\"\n * console.log(detail.children.length); // child codes\n * ```\n */\n async get(code: string): Promise<CodeDetailFull> {\n return this.client.get<CodeDetailFull>(`/api/v1/icd10/codes/${encodeURIComponent(code)}`);\n }\n\n}\n\n// ─── ICD-11 Codes Sub-resource ───\n\nclass ICD11Codes {\n constructor(private readonly client: AutoICD) {}\n\n /**\n * Search ICD-11 codes by description.\n *\n * @example\n * ```ts\n * const results = await autoicd.icd11.search(\"diabetes mellitus\");\n * ```\n */\n async search(query: string, options?: SearchOptions): Promise<ICD11CodeSearchResponse> {\n const params = new URLSearchParams({ q: query });\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options?.offset !== undefined) params.set(\"offset\", String(options.offset));\n return this.client.get<ICD11CodeSearchResponse>(`/api/v1/icd11/codes/search?${params}`);\n }\n\n /**\n * Get comprehensive details for a single ICD-11 code, including synonyms,\n * hierarchy (parent/children), chapter, and ICD-10 crosswalk mappings.\n *\n * @example\n * ```ts\n * const detail = await autoicd.icd11.get(\"5A11\");\n * console.log(detail.long_description);\n * console.log(detail.chapter?.title);\n * console.log(detail.icd10_mappings);\n * ```\n */\n async get(code: string): Promise<ICD11CodeDetailFull> {\n return this.client.get<ICD11CodeDetailFull>(`/api/v1/icd11/codes/${encodeURIComponent(code)}`);\n }\n}\n\n// ─── ICF Codes Sub-resource ───\n\nclass ICFCodes {\n constructor(private readonly client: AutoICD) {}\n\n /**\n * Code clinical text to ICF codes.\n *\n * @example\n * ```ts\n * const result = await autoicd.icf.code(\"Patient has difficulty walking\");\n * for (const entity of result.results) {\n * console.log(entity.entity_text, entity.codes[0]?.code);\n * }\n * ```\n */\n async code(text: string, options?: { topK?: number }): Promise<ICFCodingResponse> {\n return this.client.post<ICFCodingResponse>(\"/api/v1/icf/code\", {\n text,\n top_k: options?.topK,\n });\n }\n\n /**\n * Get full details for a single ICF code, including definition,\n * hierarchy (parent/children), inclusions, exclusions, and index terms.\n *\n * @example\n * ```ts\n * const detail = await autoicd.icf.lookup(\"b280\");\n * console.log(detail.title);\n * console.log(detail.definition);\n * console.log(detail.children.length);\n * ```\n */\n async lookup(code: string): Promise<ICFCodeDetail> {\n return this.client.get<ICFCodeDetail>(`/api/v1/icf/codes/${encodeURIComponent(code)}`);\n }\n\n /**\n * Search ICF codes by description.\n *\n * @example\n * ```ts\n * const results = await autoicd.icf.search(\"pain\");\n * ```\n */\n async search(query: string, options?: SearchOptions): Promise<ICFSearchResponse> {\n const params = new URLSearchParams({ q: query });\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options?.offset !== undefined) params.set(\"offset\", String(options.offset));\n return this.client.get<ICFSearchResponse>(`/api/v1/icf/codes/search?${params}`);\n }\n\n /**\n * Get the ICF Core Set for an ICD-10 diagnosis code.\n *\n * @example\n * ```ts\n * const coreSet = await autoicd.icf.coreSet(\"M54.5\");\n * console.log(coreSet.condition_name);\n * console.log(coreSet.brief.length, \"brief codes\");\n * console.log(coreSet.comprehensive.length, \"comprehensive codes\");\n * ```\n */\n async coreSet(icd10Code: string): Promise<ICFCoreSetResult> {\n return this.client.get<ICFCoreSetResult>(`/api/v1/icf/core-set/${encodeURIComponent(icd10Code)}`);\n }\n}\n\n// ─── LOINC Codes Sub-resource ───\n\nclass LOINCCodes {\n constructor(private readonly client: AutoICD) {}\n\n /**\n * Code clinical text to LOINC codes.\n *\n * Extracts lab tests, imaging orders, and clinical observations from\n * free text and matches to LOINC codes using NER + SapBERT embeddings.\n *\n * @example\n * ```ts\n * const result = await autoicd.loinc.code(\"Order CBC, glucose, and TSH\");\n * for (const entity of result.results) {\n * console.log(entity.entity_text, entity.codes[0]?.code);\n * }\n * ```\n */\n async code(text: string, options?: { topK?: number }): Promise<LOINCCodingResponse> {\n return this.client.post<LOINCCodingResponse>(\"/api/v1/loinc/code\", {\n text,\n top_k: options?.topK,\n });\n }\n\n /**\n * Get full details for a single LOINC code, including 6-axis classification,\n * definition, related names, and cross-references.\n *\n * @example\n * ```ts\n * const detail = await autoicd.loinc.lookup(\"2345-7\");\n * console.log(detail.long_common_name);\n * console.log(detail.component, detail.system);\n * ```\n */\n async lookup(code: string): Promise<LOINCCodeDetail> {\n return this.client.get<LOINCCodeDetail>(`/api/v1/loinc/codes/${encodeURIComponent(code)}`);\n }\n\n /**\n * Search LOINC codes by description.\n *\n * @example\n * ```ts\n * const results = await autoicd.loinc.search(\"glucose\");\n * ```\n */\n async search(query: string, options?: SearchOptions): Promise<LOINCSearchResponse> {\n const params = new URLSearchParams({ q: query });\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options?.offset !== undefined) params.set(\"offset\", String(options.offset));\n return this.client.get<LOINCSearchResponse>(`/api/v1/loinc/codes/search?${params}`);\n }\n}\n\n// ─── Helpers ───\n\nfunction parseRateLimit(headers: Headers): RateLimit | null {\n const limit = headers.get(\"X-RateLimit-Limit\");\n const remaining = headers.get(\"X-RateLimit-Remaining\");\n const reset = headers.get(\"X-RateLimit-Reset\");\n\n if (!limit || !remaining || !reset) return null;\n\n return {\n limit: parseInt(limit, 10),\n remaining: parseInt(remaining, 10),\n resetAt: new Date(reset),\n };\n}\n"],"mappings":"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","names":[]}
package/dist/index.mjs CHANGED
@@ -39,9 +39,13 @@ var AutoICD = class {
39
39
  /** Rate limit info from the most recent API response. */
40
40
  lastRateLimit = null;
41
41
  /** Sub-resource for ICD-10 code lookup. */
42
- codes;
42
+ icd10;
43
43
  /** Sub-resource for ICD-11 code lookup. */
44
44
  icd11;
45
+ /** Sub-resource for ICF code lookup and coding. */
46
+ icf;
47
+ /** Sub-resource for LOINC code lookup and coding. */
48
+ loinc;
45
49
  constructor(options) {
46
50
  if (!options.apiKey) {
47
51
  throw new Error("apiKey is required");
@@ -50,8 +54,10 @@ var AutoICD = class {
50
54
  this.baseURL = (options.baseURL ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
51
55
  this.timeout = options.timeout ?? DEFAULT_TIMEOUT;
52
56
  this._fetch = options.fetch ?? globalThis.fetch;
53
- this.codes = new Codes(this);
57
+ this.icd10 = new ICD10Codes(this);
54
58
  this.icd11 = new ICD11Codes(this);
59
+ this.icf = new ICFCodes(this);
60
+ this.loinc = new LOINCCodes(this);
55
61
  }
56
62
  // ─── Public Methods ───
57
63
  /**
@@ -70,7 +76,11 @@ var AutoICD = class {
70
76
  text,
71
77
  top_k: options?.topK,
72
78
  include_negated: options?.includeNegated,
73
- output_system: options?.outputSystem
79
+ output_system: options?.outputSystem,
80
+ include_icf: options?.includeIcf,
81
+ include_icd11: options?.includeIcd11,
82
+ include_snomed: options?.includeSnomed,
83
+ include_umls: options?.includeUmls
74
84
  });
75
85
  }
76
86
  /**
@@ -86,6 +96,27 @@ var AutoICD = class {
86
96
  async anonymize(text) {
87
97
  return this.post("/api/v1/anonymize", { text });
88
98
  }
99
+ /**
100
+ * Audit a chart for coding gaps, RADV risk, specificity, denial flags, and
101
+ * a reconciled problem list. Every finding carries extractive evidence spans.
102
+ *
103
+ * @example
104
+ * ```ts
105
+ * const audit = await autoicd.audit({
106
+ * text: "68yo M, type 2 diabetes, chronic systolic heart failure on furosemide.",
107
+ * codes: [{ code: "E11.9", kind: "icd10" }],
108
+ * capabilities: ["hcc", "radv", "specificity", "denial", "problem_list"],
109
+ * context: { patient: { coverage: "medicare_advantage" } },
110
+ * });
111
+ * console.log(audit.totals.estimated_revenue_recovery);
112
+ * for (const m of audit.missed) {
113
+ * console.log(`${m.code} ${m.hcc_category} $${m.estimated_revenue}`);
114
+ * }
115
+ * ```
116
+ */
117
+ async audit(request) {
118
+ return this.post("/api/v1/audit", request);
119
+ }
89
120
  // ─── Internal HTTP ───
90
121
  /** @internal */
91
122
  async get(path) {
@@ -143,7 +174,7 @@ var AutoICD = class {
143
174
  }
144
175
  }
145
176
  };
146
- var Codes = class {
177
+ var ICD10Codes = class {
147
178
  constructor(client) {
148
179
  this.client = client;
149
180
  }
@@ -152,14 +183,14 @@ var Codes = class {
152
183
  *
153
184
  * @example
154
185
  * ```ts
155
- * const results = await autoicd.codes.search("diabetes mellitus");
186
+ * const results = await autoicd.icd10.search("diabetes mellitus");
156
187
  * ```
157
188
  */
158
189
  async search(query, options) {
159
190
  const params = new URLSearchParams({ q: query });
160
191
  if (options?.limit !== void 0) params.set("limit", String(options.limit));
161
192
  if (options?.offset !== void 0) params.set("offset", String(options.offset));
162
- return this.client.get(`/api/v1/codes/search?${params}`);
193
+ return this.client.get(`/api/v1/icd10/codes/search?${params}`);
163
194
  }
164
195
  /**
165
196
  * Get comprehensive details for a single ICD-10 code, including synonyms,
@@ -167,7 +198,7 @@ var Codes = class {
167
198
  *
168
199
  * @example
169
200
  * ```ts
170
- * const detail = await autoicd.codes.get("E11.9");
201
+ * const detail = await autoicd.icd10.get("E11.9");
171
202
  * console.log(detail.long_description);
172
203
  * console.log(detail.synonyms.snomed); // SNOMED CT synonyms
173
204
  * console.log(detail.chapter?.title); // "Endocrine, Nutritional and Metabolic Diseases"
@@ -175,7 +206,7 @@ var Codes = class {
175
206
  * ```
176
207
  */
177
208
  async get(code) {
178
- return this.client.get(`/api/v1/codes/${encodeURIComponent(code)}`);
209
+ return this.client.get(`/api/v1/icd10/codes/${encodeURIComponent(code)}`);
179
210
  }
180
211
  };
181
212
  var ICD11Codes = class {
@@ -212,6 +243,124 @@ var ICD11Codes = class {
212
243
  return this.client.get(`/api/v1/icd11/codes/${encodeURIComponent(code)}`);
213
244
  }
214
245
  };
246
+ var ICFCodes = class {
247
+ constructor(client) {
248
+ this.client = client;
249
+ }
250
+ /**
251
+ * Code clinical text to ICF codes.
252
+ *
253
+ * @example
254
+ * ```ts
255
+ * const result = await autoicd.icf.code("Patient has difficulty walking");
256
+ * for (const entity of result.results) {
257
+ * console.log(entity.entity_text, entity.codes[0]?.code);
258
+ * }
259
+ * ```
260
+ */
261
+ async code(text, options) {
262
+ return this.client.post("/api/v1/icf/code", {
263
+ text,
264
+ top_k: options?.topK
265
+ });
266
+ }
267
+ /**
268
+ * Get full details for a single ICF code, including definition,
269
+ * hierarchy (parent/children), inclusions, exclusions, and index terms.
270
+ *
271
+ * @example
272
+ * ```ts
273
+ * const detail = await autoicd.icf.lookup("b280");
274
+ * console.log(detail.title);
275
+ * console.log(detail.definition);
276
+ * console.log(detail.children.length);
277
+ * ```
278
+ */
279
+ async lookup(code) {
280
+ return this.client.get(`/api/v1/icf/codes/${encodeURIComponent(code)}`);
281
+ }
282
+ /**
283
+ * Search ICF codes by description.
284
+ *
285
+ * @example
286
+ * ```ts
287
+ * const results = await autoicd.icf.search("pain");
288
+ * ```
289
+ */
290
+ async search(query, options) {
291
+ const params = new URLSearchParams({ q: query });
292
+ if (options?.limit !== void 0) params.set("limit", String(options.limit));
293
+ if (options?.offset !== void 0) params.set("offset", String(options.offset));
294
+ return this.client.get(`/api/v1/icf/codes/search?${params}`);
295
+ }
296
+ /**
297
+ * Get the ICF Core Set for an ICD-10 diagnosis code.
298
+ *
299
+ * @example
300
+ * ```ts
301
+ * const coreSet = await autoicd.icf.coreSet("M54.5");
302
+ * console.log(coreSet.condition_name);
303
+ * console.log(coreSet.brief.length, "brief codes");
304
+ * console.log(coreSet.comprehensive.length, "comprehensive codes");
305
+ * ```
306
+ */
307
+ async coreSet(icd10Code) {
308
+ return this.client.get(`/api/v1/icf/core-set/${encodeURIComponent(icd10Code)}`);
309
+ }
310
+ };
311
+ var LOINCCodes = class {
312
+ constructor(client) {
313
+ this.client = client;
314
+ }
315
+ /**
316
+ * Code clinical text to LOINC codes.
317
+ *
318
+ * Extracts lab tests, imaging orders, and clinical observations from
319
+ * free text and matches to LOINC codes using NER + SapBERT embeddings.
320
+ *
321
+ * @example
322
+ * ```ts
323
+ * const result = await autoicd.loinc.code("Order CBC, glucose, and TSH");
324
+ * for (const entity of result.results) {
325
+ * console.log(entity.entity_text, entity.codes[0]?.code);
326
+ * }
327
+ * ```
328
+ */
329
+ async code(text, options) {
330
+ return this.client.post("/api/v1/loinc/code", {
331
+ text,
332
+ top_k: options?.topK
333
+ });
334
+ }
335
+ /**
336
+ * Get full details for a single LOINC code, including 6-axis classification,
337
+ * definition, related names, and cross-references.
338
+ *
339
+ * @example
340
+ * ```ts
341
+ * const detail = await autoicd.loinc.lookup("2345-7");
342
+ * console.log(detail.long_common_name);
343
+ * console.log(detail.component, detail.system);
344
+ * ```
345
+ */
346
+ async lookup(code) {
347
+ return this.client.get(`/api/v1/loinc/codes/${encodeURIComponent(code)}`);
348
+ }
349
+ /**
350
+ * Search LOINC codes by description.
351
+ *
352
+ * @example
353
+ * ```ts
354
+ * const results = await autoicd.loinc.search("glucose");
355
+ * ```
356
+ */
357
+ async search(query, options) {
358
+ const params = new URLSearchParams({ q: query });
359
+ if (options?.limit !== void 0) params.set("limit", String(options.limit));
360
+ if (options?.offset !== void 0) params.set("offset", String(options.offset));
361
+ return this.client.get(`/api/v1/loinc/codes/search?${params}`);
362
+ }
363
+ };
215
364
  function parseRateLimit(headers) {
216
365
  const limit = headers.get("X-RateLimit-Limit");
217
366
  const remaining = headers.get("X-RateLimit-Remaining");
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/client.ts"],"sourcesContent":["import type { RateLimit } from \"./types.js\";\n\nexport class AutoICDError extends Error {\n readonly status: number;\n\n constructor(status: number, message: string) {\n super(message);\n this.name = \"AutoICDError\";\n this.status = status;\n }\n}\n\nexport class AuthenticationError extends AutoICDError {\n constructor(message = \"Invalid API key\") {\n super(401, message);\n this.name = \"AuthenticationError\";\n }\n}\n\nexport class RateLimitError extends AutoICDError {\n readonly rateLimit: RateLimit;\n\n constructor(message: string, rateLimit: RateLimit) {\n super(429, message);\n this.name = \"RateLimitError\";\n this.rateLimit = rateLimit;\n }\n}\n\nexport class NotFoundError extends AutoICDError {\n constructor(message = \"Resource not found\") {\n super(404, message);\n this.name = \"NotFoundError\";\n }\n}\n","import type {\n AutoICDOptions,\n CodeOptions,\n CodingResponse,\n SearchOptions,\n CodeSearchResponse,\n CodeDetail,\n CodeDetailFull,\n AnonymizeResponse,\n RateLimit,\n ErrorBody,\n ICD11CodeSearchResponse,\n ICD11CodeDetailFull,\n} from \"./types.js\";\nimport {\n AutoICDError,\n AuthenticationError,\n RateLimitError,\n NotFoundError,\n} from \"./errors.js\";\n\nconst DEFAULT_BASE_URL = \"https://autoicdapi.com\";\nconst DEFAULT_TIMEOUT = 30_000;\n\nexport class AutoICD {\n private readonly apiKey: string;\n private readonly baseURL: string;\n private readonly timeout: number;\n private readonly _fetch: typeof globalThis.fetch;\n\n /** Rate limit info from the most recent API response. */\n lastRateLimit: RateLimit | null = null;\n\n /** Sub-resource for ICD-10 code lookup. */\n readonly codes: Codes;\n\n /** Sub-resource for ICD-11 code lookup. */\n readonly icd11: ICD11Codes;\n\n constructor(options: AutoICDOptions) {\n if (!options.apiKey) {\n throw new Error(\"apiKey is required\");\n }\n this.apiKey = options.apiKey;\n this.baseURL = (options.baseURL ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n this._fetch = options.fetch ?? globalThis.fetch;\n this.codes = new Codes(this);\n this.icd11 = new ICD11Codes(this);\n }\n\n // ─── Public Methods ───\n\n /**\n * Code clinical text to ICD-10-CM diagnoses.\n *\n * @example\n * ```ts\n * const result = await autoicd.code(\"Patient has type 2 diabetes\");\n * for (const entity of result.entities) {\n * console.log(entity.entity_text, entity.codes[0]?.code);\n * }\n * ```\n */\n async code(text: string, options?: CodeOptions): Promise<CodingResponse> {\n return this.post<CodingResponse>(\"/api/v1/code\", {\n text,\n top_k: options?.topK,\n include_negated: options?.includeNegated,\n output_system: options?.outputSystem,\n });\n }\n\n /**\n * Anonymize PHI/PII in clinical text.\n *\n * @example\n * ```ts\n * const result = await autoicd.anonymize(\"John Smith, DOB 01/15/1980, has COPD\");\n * console.log(result.anonymized_text);\n * // \"[NAME], DOB [DATE], has COPD\"\n * ```\n */\n async anonymize(text: string): Promise<AnonymizeResponse> {\n return this.post<AnonymizeResponse>(\"/api/v1/anonymize\", { text });\n }\n\n // ─── Internal HTTP ───\n\n /** @internal */\n async get<T>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n /** @internal */\n async post<T>(path: string, body: Record<string, unknown>): Promise<T> {\n // Strip undefined values so the API receives clean JSON\n const clean = Object.fromEntries(\n Object.entries(body).filter(([, v]) => v !== undefined)\n );\n return this.request<T>(\"POST\", path, clean);\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: Record<string, unknown>\n ): Promise<T> {\n const url = `${this.baseURL}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const res = await this._fetch(url, {\n method,\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n // Parse rate limit headers\n this.lastRateLimit = parseRateLimit(res.headers);\n\n if (res.ok) {\n return (await res.json()) as T;\n }\n\n // Error responses\n const errorBody = (await res.json().catch(() => null)) as ErrorBody | null;\n const message = errorBody?.error ?? `HTTP ${res.status}`;\n\n if (res.status === 401) throw new AuthenticationError(message);\n if (res.status === 404) throw new NotFoundError(message);\n if (res.status === 429) {\n throw new RateLimitError(\n message,\n this.lastRateLimit ?? {\n limit: errorBody?.limit ?? 0,\n remaining: 0,\n resetAt: errorBody?.resetAt ? new Date(errorBody.resetAt) : new Date(),\n }\n );\n }\n\n throw new AutoICDError(res.status, message);\n } catch (err) {\n if (err instanceof AutoICDError) throw err;\n if (err instanceof DOMException && err.name === \"AbortError\") {\n throw new AutoICDError(0, `Request timed out after ${this.timeout}ms`);\n }\n throw err;\n } finally {\n clearTimeout(timer);\n }\n }\n}\n\n// ─── Codes Sub-resource ───\n\nclass Codes {\n constructor(private readonly client: AutoICD) {}\n\n /**\n * Search ICD-10 codes by description.\n *\n * @example\n * ```ts\n * const results = await autoicd.codes.search(\"diabetes mellitus\");\n * ```\n */\n async search(query: string, options?: SearchOptions): Promise<CodeSearchResponse> {\n const params = new URLSearchParams({ q: query });\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options?.offset !== undefined) params.set(\"offset\", String(options.offset));\n return this.client.get<CodeSearchResponse>(`/api/v1/codes/search?${params}`);\n }\n\n /**\n * Get comprehensive details for a single ICD-10 code, including synonyms,\n * hierarchy (parent/children), chapter, and SNOMED CT / UMLS cross-references.\n *\n * @example\n * ```ts\n * const detail = await autoicd.codes.get(\"E11.9\");\n * console.log(detail.long_description);\n * console.log(detail.synonyms.snomed); // SNOMED CT synonyms\n * console.log(detail.chapter?.title); // \"Endocrine, Nutritional and Metabolic Diseases\"\n * console.log(detail.children.length); // child codes\n * ```\n */\n async get(code: string): Promise<CodeDetailFull> {\n return this.client.get<CodeDetailFull>(`/api/v1/codes/${encodeURIComponent(code)}`);\n }\n\n}\n\n// ─── ICD-11 Codes Sub-resource ───\n\nclass ICD11Codes {\n constructor(private readonly client: AutoICD) {}\n\n /**\n * Search ICD-11 codes by description.\n *\n * @example\n * ```ts\n * const results = await autoicd.icd11.search(\"diabetes mellitus\");\n * ```\n */\n async search(query: string, options?: SearchOptions): Promise<ICD11CodeSearchResponse> {\n const params = new URLSearchParams({ q: query });\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options?.offset !== undefined) params.set(\"offset\", String(options.offset));\n return this.client.get<ICD11CodeSearchResponse>(`/api/v1/icd11/codes/search?${params}`);\n }\n\n /**\n * Get comprehensive details for a single ICD-11 code, including synonyms,\n * hierarchy (parent/children), chapter, and ICD-10 crosswalk mappings.\n *\n * @example\n * ```ts\n * const detail = await autoicd.icd11.get(\"5A11\");\n * console.log(detail.long_description);\n * console.log(detail.chapter?.title);\n * console.log(detail.icd10_mappings);\n * ```\n */\n async get(code: string): Promise<ICD11CodeDetailFull> {\n return this.client.get<ICD11CodeDetailFull>(`/api/v1/icd11/codes/${encodeURIComponent(code)}`);\n }\n}\n\n// ─── Helpers ───\n\nfunction parseRateLimit(headers: Headers): RateLimit | null {\n const limit = headers.get(\"X-RateLimit-Limit\");\n const remaining = headers.get(\"X-RateLimit-Remaining\");\n const reset = headers.get(\"X-RateLimit-Reset\");\n\n if (!limit || !remaining || !reset) return null;\n\n return {\n limit: parseInt(limit, 10),\n remaining: parseInt(remaining, 10),\n resetAt: new Date(reset),\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/client.ts"],"sourcesContent":["import type { RateLimit } from \"./types.js\";\n\nexport class AutoICDError extends Error {\n readonly status: number;\n\n constructor(status: number, message: string) {\n super(message);\n this.name = \"AutoICDError\";\n this.status = status;\n }\n}\n\nexport class AuthenticationError extends AutoICDError {\n constructor(message = \"Invalid API key\") {\n super(401, message);\n this.name = \"AuthenticationError\";\n }\n}\n\nexport class RateLimitError extends AutoICDError {\n readonly rateLimit: RateLimit;\n\n constructor(message: string, rateLimit: RateLimit) {\n super(429, message);\n this.name = \"RateLimitError\";\n this.rateLimit = rateLimit;\n }\n}\n\nexport class NotFoundError extends AutoICDError {\n constructor(message = \"Resource not found\") {\n super(404, message);\n this.name = \"NotFoundError\";\n }\n}\n","import type {\n AutoICDOptions,\n CodeOptions,\n CodingResponse,\n SearchOptions,\n CodeSearchResponse,\n CodeDetail,\n CodeDetailFull,\n AnonymizeResponse,\n RateLimit,\n ErrorBody,\n ICD11CodeSearchResponse,\n ICD11CodeDetailFull,\n ICFCodingResponse,\n ICFCodeDetail,\n ICFSearchResponse,\n ICFCoreSetResult,\n LOINCCodeDetail,\n LOINCSearchResponse,\n LOINCCodingResponse,\n AuditRequest,\n AuditResponse,\n} from \"./types.js\";\nimport {\n AutoICDError,\n AuthenticationError,\n RateLimitError,\n NotFoundError,\n} from \"./errors.js\";\n\nconst DEFAULT_BASE_URL = \"https://autoicdapi.com\";\nconst DEFAULT_TIMEOUT = 30_000;\n\nexport class AutoICD {\n private readonly apiKey: string;\n private readonly baseURL: string;\n private readonly timeout: number;\n private readonly _fetch: typeof globalThis.fetch;\n\n /** Rate limit info from the most recent API response. */\n lastRateLimit: RateLimit | null = null;\n\n /** Sub-resource for ICD-10 code lookup. */\n readonly icd10: ICD10Codes;\n\n /** Sub-resource for ICD-11 code lookup. */\n readonly icd11: ICD11Codes;\n\n /** Sub-resource for ICF code lookup and coding. */\n readonly icf: ICFCodes;\n\n /** Sub-resource for LOINC code lookup and coding. */\n readonly loinc: LOINCCodes;\n\n constructor(options: AutoICDOptions) {\n if (!options.apiKey) {\n throw new Error(\"apiKey is required\");\n }\n this.apiKey = options.apiKey;\n this.baseURL = (options.baseURL ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n this._fetch = options.fetch ?? globalThis.fetch;\n this.icd10 = new ICD10Codes(this);\n this.icd11 = new ICD11Codes(this);\n this.icf = new ICFCodes(this);\n this.loinc = new LOINCCodes(this);\n }\n\n // ─── Public Methods ───\n\n /**\n * Code clinical text to ICD-10-CM diagnoses.\n *\n * @example\n * ```ts\n * const result = await autoicd.code(\"Patient has type 2 diabetes\");\n * for (const entity of result.entities) {\n * console.log(entity.entity_text, entity.codes[0]?.code);\n * }\n * ```\n */\n async code(text: string, options?: CodeOptions): Promise<CodingResponse> {\n return this.post<CodingResponse>(\"/api/v1/code\", {\n text,\n top_k: options?.topK,\n include_negated: options?.includeNegated,\n output_system: options?.outputSystem,\n include_icf: options?.includeIcf,\n include_icd11: options?.includeIcd11,\n include_snomed: options?.includeSnomed,\n include_umls: options?.includeUmls,\n });\n }\n\n /**\n * Anonymize PHI/PII in clinical text.\n *\n * @example\n * ```ts\n * const result = await autoicd.anonymize(\"John Smith, DOB 01/15/1980, has COPD\");\n * console.log(result.anonymized_text);\n * // \"[NAME], DOB [DATE], has COPD\"\n * ```\n */\n async anonymize(text: string): Promise<AnonymizeResponse> {\n return this.post<AnonymizeResponse>(\"/api/v1/anonymize\", { text });\n }\n\n /**\n * Audit a chart for coding gaps, RADV risk, specificity, denial flags, and\n * a reconciled problem list. Every finding carries extractive evidence spans.\n *\n * @example\n * ```ts\n * const audit = await autoicd.audit({\n * text: \"68yo M, type 2 diabetes, chronic systolic heart failure on furosemide.\",\n * codes: [{ code: \"E11.9\", kind: \"icd10\" }],\n * capabilities: [\"hcc\", \"radv\", \"specificity\", \"denial\", \"problem_list\"],\n * context: { patient: { coverage: \"medicare_advantage\" } },\n * });\n * console.log(audit.totals.estimated_revenue_recovery);\n * for (const m of audit.missed) {\n * console.log(`${m.code} ${m.hcc_category} $${m.estimated_revenue}`);\n * }\n * ```\n */\n async audit(request: AuditRequest): Promise<AuditResponse> {\n return this.post<AuditResponse>(\"/api/v1/audit\", request as unknown as Record<string, unknown>);\n }\n\n // ─── Internal HTTP ───\n\n /** @internal */\n async get<T>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n /** @internal */\n async post<T>(path: string, body: Record<string, unknown>): Promise<T> {\n // Strip undefined values so the API receives clean JSON\n const clean = Object.fromEntries(\n Object.entries(body).filter(([, v]) => v !== undefined)\n );\n return this.request<T>(\"POST\", path, clean);\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: Record<string, unknown>\n ): Promise<T> {\n const url = `${this.baseURL}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const res = await this._fetch(url, {\n method,\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n // Parse rate limit headers\n this.lastRateLimit = parseRateLimit(res.headers);\n\n if (res.ok) {\n return (await res.json()) as T;\n }\n\n // Error responses\n const errorBody = (await res.json().catch(() => null)) as ErrorBody | null;\n const message = errorBody?.error ?? `HTTP ${res.status}`;\n\n if (res.status === 401) throw new AuthenticationError(message);\n if (res.status === 404) throw new NotFoundError(message);\n if (res.status === 429) {\n throw new RateLimitError(\n message,\n this.lastRateLimit ?? {\n limit: errorBody?.limit ?? 0,\n remaining: 0,\n resetAt: errorBody?.resetAt ? new Date(errorBody.resetAt) : new Date(),\n }\n );\n }\n\n throw new AutoICDError(res.status, message);\n } catch (err) {\n if (err instanceof AutoICDError) throw err;\n if (err instanceof DOMException && err.name === \"AbortError\") {\n throw new AutoICDError(0, `Request timed out after ${this.timeout}ms`);\n }\n throw err;\n } finally {\n clearTimeout(timer);\n }\n }\n}\n\n// ─── ICD-10 Codes Sub-resource ───\n\nclass ICD10Codes {\n constructor(private readonly client: AutoICD) {}\n\n /**\n * Search ICD-10 codes by description.\n *\n * @example\n * ```ts\n * const results = await autoicd.icd10.search(\"diabetes mellitus\");\n * ```\n */\n async search(query: string, options?: SearchOptions): Promise<CodeSearchResponse> {\n const params = new URLSearchParams({ q: query });\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options?.offset !== undefined) params.set(\"offset\", String(options.offset));\n return this.client.get<CodeSearchResponse>(`/api/v1/icd10/codes/search?${params}`);\n }\n\n /**\n * Get comprehensive details for a single ICD-10 code, including synonyms,\n * hierarchy (parent/children), chapter, and SNOMED CT / UMLS cross-references.\n *\n * @example\n * ```ts\n * const detail = await autoicd.icd10.get(\"E11.9\");\n * console.log(detail.long_description);\n * console.log(detail.synonyms.snomed); // SNOMED CT synonyms\n * console.log(detail.chapter?.title); // \"Endocrine, Nutritional and Metabolic Diseases\"\n * console.log(detail.children.length); // child codes\n * ```\n */\n async get(code: string): Promise<CodeDetailFull> {\n return this.client.get<CodeDetailFull>(`/api/v1/icd10/codes/${encodeURIComponent(code)}`);\n }\n\n}\n\n// ─── ICD-11 Codes Sub-resource ───\n\nclass ICD11Codes {\n constructor(private readonly client: AutoICD) {}\n\n /**\n * Search ICD-11 codes by description.\n *\n * @example\n * ```ts\n * const results = await autoicd.icd11.search(\"diabetes mellitus\");\n * ```\n */\n async search(query: string, options?: SearchOptions): Promise<ICD11CodeSearchResponse> {\n const params = new URLSearchParams({ q: query });\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options?.offset !== undefined) params.set(\"offset\", String(options.offset));\n return this.client.get<ICD11CodeSearchResponse>(`/api/v1/icd11/codes/search?${params}`);\n }\n\n /**\n * Get comprehensive details for a single ICD-11 code, including synonyms,\n * hierarchy (parent/children), chapter, and ICD-10 crosswalk mappings.\n *\n * @example\n * ```ts\n * const detail = await autoicd.icd11.get(\"5A11\");\n * console.log(detail.long_description);\n * console.log(detail.chapter?.title);\n * console.log(detail.icd10_mappings);\n * ```\n */\n async get(code: string): Promise<ICD11CodeDetailFull> {\n return this.client.get<ICD11CodeDetailFull>(`/api/v1/icd11/codes/${encodeURIComponent(code)}`);\n }\n}\n\n// ─── ICF Codes Sub-resource ───\n\nclass ICFCodes {\n constructor(private readonly client: AutoICD) {}\n\n /**\n * Code clinical text to ICF codes.\n *\n * @example\n * ```ts\n * const result = await autoicd.icf.code(\"Patient has difficulty walking\");\n * for (const entity of result.results) {\n * console.log(entity.entity_text, entity.codes[0]?.code);\n * }\n * ```\n */\n async code(text: string, options?: { topK?: number }): Promise<ICFCodingResponse> {\n return this.client.post<ICFCodingResponse>(\"/api/v1/icf/code\", {\n text,\n top_k: options?.topK,\n });\n }\n\n /**\n * Get full details for a single ICF code, including definition,\n * hierarchy (parent/children), inclusions, exclusions, and index terms.\n *\n * @example\n * ```ts\n * const detail = await autoicd.icf.lookup(\"b280\");\n * console.log(detail.title);\n * console.log(detail.definition);\n * console.log(detail.children.length);\n * ```\n */\n async lookup(code: string): Promise<ICFCodeDetail> {\n return this.client.get<ICFCodeDetail>(`/api/v1/icf/codes/${encodeURIComponent(code)}`);\n }\n\n /**\n * Search ICF codes by description.\n *\n * @example\n * ```ts\n * const results = await autoicd.icf.search(\"pain\");\n * ```\n */\n async search(query: string, options?: SearchOptions): Promise<ICFSearchResponse> {\n const params = new URLSearchParams({ q: query });\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options?.offset !== undefined) params.set(\"offset\", String(options.offset));\n return this.client.get<ICFSearchResponse>(`/api/v1/icf/codes/search?${params}`);\n }\n\n /**\n * Get the ICF Core Set for an ICD-10 diagnosis code.\n *\n * @example\n * ```ts\n * const coreSet = await autoicd.icf.coreSet(\"M54.5\");\n * console.log(coreSet.condition_name);\n * console.log(coreSet.brief.length, \"brief codes\");\n * console.log(coreSet.comprehensive.length, \"comprehensive codes\");\n * ```\n */\n async coreSet(icd10Code: string): Promise<ICFCoreSetResult> {\n return this.client.get<ICFCoreSetResult>(`/api/v1/icf/core-set/${encodeURIComponent(icd10Code)}`);\n }\n}\n\n// ─── LOINC Codes Sub-resource ───\n\nclass LOINCCodes {\n constructor(private readonly client: AutoICD) {}\n\n /**\n * Code clinical text to LOINC codes.\n *\n * Extracts lab tests, imaging orders, and clinical observations from\n * free text and matches to LOINC codes using NER + SapBERT embeddings.\n *\n * @example\n * ```ts\n * const result = await autoicd.loinc.code(\"Order CBC, glucose, and TSH\");\n * for (const entity of result.results) {\n * console.log(entity.entity_text, entity.codes[0]?.code);\n * }\n * ```\n */\n async code(text: string, options?: { topK?: number }): Promise<LOINCCodingResponse> {\n return this.client.post<LOINCCodingResponse>(\"/api/v1/loinc/code\", {\n text,\n top_k: options?.topK,\n });\n }\n\n /**\n * Get full details for a single LOINC code, including 6-axis classification,\n * definition, related names, and cross-references.\n *\n * @example\n * ```ts\n * const detail = await autoicd.loinc.lookup(\"2345-7\");\n * console.log(detail.long_common_name);\n * console.log(detail.component, detail.system);\n * ```\n */\n async lookup(code: string): Promise<LOINCCodeDetail> {\n return this.client.get<LOINCCodeDetail>(`/api/v1/loinc/codes/${encodeURIComponent(code)}`);\n }\n\n /**\n * Search LOINC codes by description.\n *\n * @example\n * ```ts\n * const results = await autoicd.loinc.search(\"glucose\");\n * ```\n */\n async search(query: string, options?: SearchOptions): Promise<LOINCSearchResponse> {\n const params = new URLSearchParams({ q: query });\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options?.offset !== undefined) params.set(\"offset\", String(options.offset));\n return this.client.get<LOINCSearchResponse>(`/api/v1/loinc/codes/search?${params}`);\n }\n}\n\n// ─── Helpers ───\n\nfunction parseRateLimit(headers: Headers): RateLimit | null {\n const limit = headers.get(\"X-RateLimit-Limit\");\n const remaining = headers.get(\"X-RateLimit-Remaining\");\n const reset = headers.get(\"X-RateLimit-Reset\");\n\n if (!limit || !remaining || !reset) return null;\n\n return {\n limit: parseInt(limit, 10),\n remaining: parseInt(remaining, 10),\n resetAt: new Date(reset),\n };\n}\n"],"mappings":";AAEO,IAAM,eAAN,cAA2B,MAAM;AAAA,EAC7B;AAAA,EAET,YAAY,QAAgB,SAAiB;AAC3C,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS;AAAA,EAChB;AACF;AAEO,IAAM,sBAAN,cAAkC,aAAa;AAAA,EACpD,YAAY,UAAU,mBAAmB;AACvC,UAAM,KAAK,OAAO;AAClB,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,iBAAN,cAA6B,aAAa;AAAA,EACtC;AAAA,EAET,YAAY,SAAiB,WAAsB;AACjD,UAAM,KAAK,OAAO;AAClB,SAAK,OAAO;AACZ,SAAK,YAAY;AAAA,EACnB;AACF;AAEO,IAAM,gBAAN,cAA4B,aAAa;AAAA,EAC9C,YAAY,UAAU,sBAAsB;AAC1C,UAAM,KAAK,OAAO;AAClB,SAAK,OAAO;AAAA,EACd;AACF;;;ACJA,IAAM,mBAAmB;AACzB,IAAM,kBAAkB;AAEjB,IAAM,UAAN,MAAc;AAAA,EACF;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGjB,gBAAkC;AAAA;AAAA,EAGzB;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA;AAAA,EAET,YAAY,SAAyB;AACnC,QAAI,CAAC,QAAQ,QAAQ;AACnB,YAAM,IAAI,MAAM,oBAAoB;AAAA,IACtC;AACA,SAAK,SAAS,QAAQ;AACtB,SAAK,WAAW,QAAQ,WAAW,kBAAkB,QAAQ,QAAQ,EAAE;AACvE,SAAK,UAAU,QAAQ,WAAW;AAClC,SAAK,SAAS,QAAQ,SAAS,WAAW;AAC1C,SAAK,QAAQ,IAAI,WAAW,IAAI;AAChC,SAAK,QAAQ,IAAI,WAAW,IAAI;AAChC,SAAK,MAAM,IAAI,SAAS,IAAI;AAC5B,SAAK,QAAQ,IAAI,WAAW,IAAI;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,KAAK,MAAc,SAAgD;AACvE,WAAO,KAAK,KAAqB,gBAAgB;AAAA,MAC/C;AAAA,MACA,OAAO,SAAS;AAAA,MAChB,iBAAiB,SAAS;AAAA,MAC1B,eAAe,SAAS;AAAA,MACxB,aAAa,SAAS;AAAA,MACtB,eAAe,SAAS;AAAA,MACxB,gBAAgB,SAAS;AAAA,MACzB,cAAc,SAAS;AAAA,IACzB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,UAAU,MAA0C;AACxD,WAAO,KAAK,KAAwB,qBAAqB,EAAE,KAAK,CAAC;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,MAAM,MAAM,SAA+C;AACzD,WAAO,KAAK,KAAoB,iBAAiB,OAA6C;AAAA,EAChG;AAAA;AAAA;AAAA,EAKA,MAAM,IAAO,MAA0B;AACrC,WAAO,KAAK,QAAW,OAAO,IAAI;AAAA,EACpC;AAAA;AAAA,EAGA,MAAM,KAAQ,MAAc,MAA2C;AAErE,UAAM,QAAQ,OAAO;AAAA,MACnB,OAAO,QAAQ,IAAI,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAS;AAAA,IACxD;AACA,WAAO,KAAK,QAAW,QAAQ,MAAM,KAAK;AAAA,EAC5C;AAAA,EAEA,MAAc,QACZ,QACA,MACA,MACY;AACZ,UAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI;AAClC,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,QAAQ,WAAW,MAAM,WAAW,MAAM,GAAG,KAAK,OAAO;AAE/D,QAAI;AACF,YAAM,MAAM,MAAM,KAAK,OAAO,KAAK;AAAA,QACjC;AAAA,QACA,SAAS;AAAA,UACP,eAAe,UAAU,KAAK,MAAM;AAAA,UACpC,gBAAgB;AAAA,UAChB,QAAQ;AAAA,QACV;AAAA,QACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,QACpC,QAAQ,WAAW;AAAA,MACrB,CAAC;AAGD,WAAK,gBAAgB,eAAe,IAAI,OAAO;AAE/C,UAAI,IAAI,IAAI;AACV,eAAQ,MAAM,IAAI,KAAK;AAAA,MACzB;AAGA,YAAM,YAAa,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI;AACpD,YAAM,UAAU,WAAW,SAAS,QAAQ,IAAI,MAAM;AAEtD,UAAI,IAAI,WAAW,IAAK,OAAM,IAAI,oBAAoB,OAAO;AAC7D,UAAI,IAAI,WAAW,IAAK,OAAM,IAAI,cAAc,OAAO;AACvD,UAAI,IAAI,WAAW,KAAK;AACtB,cAAM,IAAI;AAAA,UACR;AAAA,UACA,KAAK,iBAAiB;AAAA,YACpB,OAAO,WAAW,SAAS;AAAA,YAC3B,WAAW;AAAA,YACX,SAAS,WAAW,UAAU,IAAI,KAAK,UAAU,OAAO,IAAI,oBAAI,KAAK;AAAA,UACvE;AAAA,QACF;AAAA,MACF;AAEA,YAAM,IAAI,aAAa,IAAI,QAAQ,OAAO;AAAA,IAC5C,SAAS,KAAK;AACZ,UAAI,eAAe,aAAc,OAAM;AACvC,UAAI,eAAe,gBAAgB,IAAI,SAAS,cAAc;AAC5D,cAAM,IAAI,aAAa,GAAG,2BAA2B,KAAK,OAAO,IAAI;AAAA,MACvE;AACA,YAAM;AAAA,IACR,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AACF;AAIA,IAAM,aAAN,MAAiB;AAAA,EACf,YAA6B,QAAiB;AAAjB;AAAA,EAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU/C,MAAM,OAAO,OAAe,SAAsD;AAChF,UAAM,SAAS,IAAI,gBAAgB,EAAE,GAAG,MAAM,CAAC;AAC/C,QAAI,SAAS,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,QAAQ,KAAK,CAAC;AAC3E,QAAI,SAAS,WAAW,OAAW,QAAO,IAAI,UAAU,OAAO,QAAQ,MAAM,CAAC;AAC9E,WAAO,KAAK,OAAO,IAAwB,8BAA8B,MAAM,EAAE;AAAA,EACnF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,IAAI,MAAuC;AAC/C,WAAO,KAAK,OAAO,IAAoB,uBAAuB,mBAAmB,IAAI,CAAC,EAAE;AAAA,EAC1F;AAEF;AAIA,IAAM,aAAN,MAAiB;AAAA,EACf,YAA6B,QAAiB;AAAjB;AAAA,EAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU/C,MAAM,OAAO,OAAe,SAA2D;AACrF,UAAM,SAAS,IAAI,gBAAgB,EAAE,GAAG,MAAM,CAAC;AAC/C,QAAI,SAAS,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,QAAQ,KAAK,CAAC;AAC3E,QAAI,SAAS,WAAW,OAAW,QAAO,IAAI,UAAU,OAAO,QAAQ,MAAM,CAAC;AAC9E,WAAO,KAAK,OAAO,IAA6B,8BAA8B,MAAM,EAAE;AAAA,EACxF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,IAAI,MAA4C;AACpD,WAAO,KAAK,OAAO,IAAyB,uBAAuB,mBAAmB,IAAI,CAAC,EAAE;AAAA,EAC/F;AACF;AAIA,IAAM,WAAN,MAAe;AAAA,EACb,YAA6B,QAAiB;AAAjB;AAAA,EAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAa/C,MAAM,KAAK,MAAc,SAAyD;AAChF,WAAO,KAAK,OAAO,KAAwB,oBAAoB;AAAA,MAC7D;AAAA,MACA,OAAO,SAAS;AAAA,IAClB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,OAAO,MAAsC;AACjD,WAAO,KAAK,OAAO,IAAmB,qBAAqB,mBAAmB,IAAI,CAAC,EAAE;AAAA,EACvF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,OAAO,OAAe,SAAqD;AAC/E,UAAM,SAAS,IAAI,gBAAgB,EAAE,GAAG,MAAM,CAAC;AAC/C,QAAI,SAAS,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,QAAQ,KAAK,CAAC;AAC3E,QAAI,SAAS,WAAW,OAAW,QAAO,IAAI,UAAU,OAAO,QAAQ,MAAM,CAAC;AAC9E,WAAO,KAAK,OAAO,IAAuB,4BAA4B,MAAM,EAAE;AAAA,EAChF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,QAAQ,WAA8C;AAC1D,WAAO,KAAK,OAAO,IAAsB,wBAAwB,mBAAmB,SAAS,CAAC,EAAE;AAAA,EAClG;AACF;AAIA,IAAM,aAAN,MAAiB;AAAA,EACf,YAA6B,QAAiB;AAAjB;AAAA,EAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgB/C,MAAM,KAAK,MAAc,SAA2D;AAClF,WAAO,KAAK,OAAO,KAA0B,sBAAsB;AAAA,MACjE;AAAA,MACA,OAAO,SAAS;AAAA,IAClB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,OAAO,MAAwC;AACnD,WAAO,KAAK,OAAO,IAAqB,uBAAuB,mBAAmB,IAAI,CAAC,EAAE;AAAA,EAC3F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,OAAO,OAAe,SAAuD;AACjF,UAAM,SAAS,IAAI,gBAAgB,EAAE,GAAG,MAAM,CAAC;AAC/C,QAAI,SAAS,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,QAAQ,KAAK,CAAC;AAC3E,QAAI,SAAS,WAAW,OAAW,QAAO,IAAI,UAAU,OAAO,QAAQ,MAAM,CAAC;AAC9E,WAAO,KAAK,OAAO,IAAyB,8BAA8B,MAAM,EAAE;AAAA,EACpF;AACF;AAIA,SAAS,eAAe,SAAoC;AAC1D,QAAM,QAAQ,QAAQ,IAAI,mBAAmB;AAC7C,QAAM,YAAY,QAAQ,IAAI,uBAAuB;AACrD,QAAM,QAAQ,QAAQ,IAAI,mBAAmB;AAE7C,MAAI,CAAC,SAAS,CAAC,aAAa,CAAC,MAAO,QAAO;AAE3C,SAAO;AAAA,IACL,OAAO,SAAS,OAAO,EAAE;AAAA,IACzB,WAAW,SAAS,WAAW,EAAE;AAAA,IACjC,SAAS,IAAI,KAAK,KAAK;AAAA,EACzB;AACF;","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "autoicd-js",
3
- "version": "0.5.1",
4
- "description": "ICD-10 & ICD-11 medical coding SDK — convert clinical text to ICD-10-CM and ICD-11 diagnosis codes with AI-powered NLP. Automated medical coding, PHI de-identification, code search, and ICD-10/ICD-11 crosswalk for EHR, billing, and health-tech apps.",
3
+ "version": "0.7.0",
4
+ "description": "AI medical coding SDK — convert clinical text to ICD-10-CM and ICD-11 diagnosis codes with AI-powered NLP. Automated ICD-10 coding, PHI de-identification, code search, and ICD-10/ICD-11 crosswalk for EHR, billing, and health-tech apps.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",
@@ -55,7 +55,13 @@
55
55
  "icd-11-api",
56
56
  "icd-10-icd-11-crosswalk",
57
57
  "autoicd",
58
- "autoicd-api"
58
+ "autoicd-api",
59
+ "ai-medical-coding",
60
+ "icd-ai",
61
+ "ai-icd-10",
62
+ "automated-diagnosis-coding",
63
+ "ai-medical-coder",
64
+ "computer-assisted-coding"
59
65
  ],
60
66
  "author": "AutoICD",
61
67
  "license": "MIT",