autoicd-js 0.5.1 → 0.6.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 +57 -7
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +7 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +7 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
[](https://www.typescriptlang.org/)
|
|
6
6
|
|
|
7
|
-
Official TypeScript SDK for the [AutoICD API](https://autoicdapi.com) — clinical text to ICD-10-CM diagnosis codes, powered by AI and medical NLP.
|
|
7
|
+
Official TypeScript SDK for the [AutoICD API](https://autoicdapi.com) — clinical text to ICD-10-CM and ICD-11 diagnosis codes, powered by AI and medical NLP.
|
|
8
8
|
|
|
9
9
|
Zero dependencies. Works in **Node.js 18+**, **Deno**, **Bun**, and **edge runtimes**.
|
|
10
10
|
|
|
@@ -16,8 +16,9 @@ Zero dependencies. Works in **Node.js 18+**, **Deno**, **Bun**, and **edge runti
|
|
|
16
16
|
|
|
17
17
|
| | |
|
|
18
18
|
|---|---|
|
|
19
|
-
| **AI-Powered ICD-10 Coding** | Clinical NLP extracts diagnoses from free-text notes and maps them to ICD-10-CM codes — no manual lookup required |
|
|
19
|
+
| **AI-Powered ICD-10 & ICD-11 Coding** | Clinical NLP extracts diagnoses from free-text notes and maps them to ICD-10-CM or ICD-11 codes — no manual lookup required |
|
|
20
20
|
| **74,000+ ICD-10-CM Codes** | Full 2025 code set enriched with SNOMED CT synonyms for comprehensive matching |
|
|
21
|
+
| **ICD-11 Support** | Search and look up ICD-11 codes, with full ICD-10 ↔ ICD-11 crosswalk mappings |
|
|
21
22
|
| **Negation & Context Detection** | Knows the difference between "patient has diabetes" and "patient denies diabetes" — flags negated, historical, uncertain, and family-history mentions |
|
|
22
23
|
| **PHI De-identification** | HIPAA-compliant anonymization of names, dates, SSNs, phone numbers, emails, addresses, MRNs, and ages |
|
|
23
24
|
| **Confidence Scoring** | Every code match includes a similarity score and confidence level so you can set your own acceptance thresholds |
|
|
@@ -106,10 +107,10 @@ const result = await autoicd.code(
|
|
|
106
107
|
Search the full ICD-10-CM 2025 code set by description. Perfect for building code lookup UIs, autocomplete fields, and validation workflows.
|
|
107
108
|
|
|
108
109
|
```ts
|
|
109
|
-
const results = await autoicd.
|
|
110
|
+
const results = await autoicd.icd10.search("diabetes mellitus");
|
|
110
111
|
// results.codes → [{ code: "E11.9", short_description: "...", long_description: "...", is_billable: true }, ...]
|
|
111
112
|
|
|
112
|
-
const results = await autoicd.
|
|
113
|
+
const results = await autoicd.icd10.search("heart failure", { limit: 5 });
|
|
113
114
|
```
|
|
114
115
|
|
|
115
116
|
### ICD-10 Code Details
|
|
@@ -117,7 +118,7 @@ const results = await autoicd.codes.search("heart failure", { limit: 5 });
|
|
|
117
118
|
Get full details for any ICD-10-CM code — descriptions, billable status, synonyms, hierarchy, and chapter classification.
|
|
118
119
|
|
|
119
120
|
```ts
|
|
120
|
-
const detail = await autoicd.
|
|
121
|
+
const detail = await autoicd.icd10.get("E11.9");
|
|
121
122
|
console.log(detail.code); // "E11.9"
|
|
122
123
|
console.log(detail.long_description); // "Type 2 diabetes mellitus without complications"
|
|
123
124
|
console.log(detail.is_billable); // true
|
|
@@ -125,6 +126,47 @@ console.log(detail.synonyms.snomed); // ["Diabetes mellitus type 2", ...]
|
|
|
125
126
|
console.log(detail.chapter?.title); // "Endocrine, Nutritional and Metabolic Diseases"
|
|
126
127
|
```
|
|
127
128
|
|
|
129
|
+
### ICD-11 Code Search
|
|
130
|
+
|
|
131
|
+
Search the ICD-11 code set by description. The AutoICD API includes the full WHO ICD-11 MMS hierarchy.
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
const results = await autoicd.icd11.search("diabetes mellitus");
|
|
135
|
+
// results.codes → [{ code: "5A11", short_description: "...", foundation_uri: "..." }, ...]
|
|
136
|
+
|
|
137
|
+
const results = await autoicd.icd11.search("heart failure", { limit: 5 });
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### ICD-11 Code Details & Crosswalk
|
|
141
|
+
|
|
142
|
+
Get full details for any ICD-11 code — descriptions, Foundation URI, hierarchy, synonyms, and ICD-10 crosswalk mappings.
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
const detail = await autoicd.icd11.get("5A11");
|
|
146
|
+
console.log(detail.code); // "5A11"
|
|
147
|
+
console.log(detail.short_description); // "Type 2 diabetes mellitus"
|
|
148
|
+
console.log(detail.foundation_uri); // "http://id.who.int/icd/entity/1691003785"
|
|
149
|
+
console.log(detail.chapter?.title); // "Endocrine, nutritional or metabolic diseases"
|
|
150
|
+
|
|
151
|
+
// ICD-10 crosswalk
|
|
152
|
+
for (const mapping of detail.icd10_mappings) {
|
|
153
|
+
console.log(`${mapping.code} — ${mapping.description} (${mapping.mapping_type})`);
|
|
154
|
+
// "E11.9 — Type 2 diabetes mellitus without complications (equivalent)"
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### ICD-10 → ICD-11 Crosswalk
|
|
159
|
+
|
|
160
|
+
ICD-10 code details now include ICD-11 crosswalk mappings when available:
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
const detail = await autoicd.icd10.get("E11.9");
|
|
164
|
+
for (const mapping of detail.icd11_mappings ?? []) {
|
|
165
|
+
console.log(`${mapping.code} — ${mapping.description}`);
|
|
166
|
+
// "5A11 — Type 2 diabetes mellitus"
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
128
170
|
### PHI De-identification
|
|
129
171
|
|
|
130
172
|
Strip protected health information from clinical notes before storage or analysis. HIPAA-compliant de-identification for names, dates, SSNs, phone numbers, emails, addresses, MRNs, and ages.
|
|
@@ -235,8 +277,10 @@ Full REST API documentation at [autoicdapi.com/docs](https://autoicdapi.com/docs
|
|
|
235
277
|
|--------|-------------|
|
|
236
278
|
| `autoicd.code(text, options?)` | Code clinical text to ICD-10-CM diagnoses |
|
|
237
279
|
| `autoicd.anonymize(text)` | De-identify PHI/PII in clinical text |
|
|
238
|
-
| `autoicd.
|
|
239
|
-
| `autoicd.
|
|
280
|
+
| `autoicd.icd10.search(query, options?)` | Search ICD-10-CM codes by description |
|
|
281
|
+
| `autoicd.icd10.get(code)` | Get details for an ICD-10-CM code (incl. ICD-11 crosswalk) |
|
|
282
|
+
| `autoicd.icd11.search(query, options?)` | Search ICD-11 codes by description |
|
|
283
|
+
| `autoicd.icd11.get(code)` | Get details for an ICD-11 code (incl. ICD-10 crosswalk) |
|
|
240
284
|
|
|
241
285
|
---
|
|
242
286
|
|
|
@@ -255,6 +299,10 @@ import type {
|
|
|
255
299
|
AnonymizeResponse,
|
|
256
300
|
PIIEntity,
|
|
257
301
|
RateLimit,
|
|
302
|
+
ICD11CodeDetail,
|
|
303
|
+
ICD11CodeDetailFull,
|
|
304
|
+
ICD11CodeSearchResponse,
|
|
305
|
+
CrosswalkMapping,
|
|
258
306
|
} from "autoicd";
|
|
259
307
|
```
|
|
260
308
|
|
|
@@ -272,6 +320,8 @@ import type {
|
|
|
272
320
|
- [AutoICD API](https://autoicdapi.com) — Homepage and API key management
|
|
273
321
|
- [API Documentation](https://autoicdapi.com/docs) — Full REST API reference
|
|
274
322
|
- [ICD-10-CM Code Directory](https://autoicdapi.com/icd10) — Browse all 74,000+ diagnosis codes
|
|
323
|
+
- [ICD-11 Code Directory](https://autoicdapi.com/icd11) — Browse the WHO ICD-11 MMS hierarchy
|
|
324
|
+
- [ICD-10 ↔ ICD-11 Crosswalk](https://autoicdapi.com/icd10-to-icd11) — Map codes between revisions
|
|
275
325
|
- [ICD-10 Codes by Condition](https://autoicdapi.com/icd10/condition) — Find codes for common conditions
|
|
276
326
|
- [Python SDK](https://pypi.org/project/autoicd/) — `pip install autoicd`
|
|
277
327
|
- [MCP Server](https://www.npmjs.com/package/autoicd-mcp) — For Claude Desktop, Cursor, VS Code
|
package/dist/index.d.mts
CHANGED
|
@@ -209,7 +209,7 @@ declare class AutoICD {
|
|
|
209
209
|
/** Rate limit info from the most recent API response. */
|
|
210
210
|
lastRateLimit: RateLimit | null;
|
|
211
211
|
/** Sub-resource for ICD-10 code lookup. */
|
|
212
|
-
readonly
|
|
212
|
+
readonly icd10: ICD10Codes;
|
|
213
213
|
/** Sub-resource for ICD-11 code lookup. */
|
|
214
214
|
readonly icd11: ICD11Codes;
|
|
215
215
|
constructor(options: AutoICDOptions);
|
|
@@ -242,7 +242,7 @@ declare class AutoICD {
|
|
|
242
242
|
post<T>(path: string, body: Record<string, unknown>): Promise<T>;
|
|
243
243
|
private request;
|
|
244
244
|
}
|
|
245
|
-
declare class
|
|
245
|
+
declare class ICD10Codes {
|
|
246
246
|
private readonly client;
|
|
247
247
|
constructor(client: AutoICD);
|
|
248
248
|
/**
|
|
@@ -250,7 +250,7 @@ declare class Codes {
|
|
|
250
250
|
*
|
|
251
251
|
* @example
|
|
252
252
|
* ```ts
|
|
253
|
-
* const results = await autoicd.
|
|
253
|
+
* const results = await autoicd.icd10.search("diabetes mellitus");
|
|
254
254
|
* ```
|
|
255
255
|
*/
|
|
256
256
|
search(query: string, options?: SearchOptions): Promise<CodeSearchResponse>;
|
|
@@ -260,7 +260,7 @@ declare class Codes {
|
|
|
260
260
|
*
|
|
261
261
|
* @example
|
|
262
262
|
* ```ts
|
|
263
|
-
* const detail = await autoicd.
|
|
263
|
+
* const detail = await autoicd.icd10.get("E11.9");
|
|
264
264
|
* console.log(detail.long_description);
|
|
265
265
|
* console.log(detail.synonyms.snomed); // SNOMED CT synonyms
|
|
266
266
|
* console.log(detail.chapter?.title); // "Endocrine, Nutritional and Metabolic Diseases"
|
package/dist/index.d.ts
CHANGED
|
@@ -209,7 +209,7 @@ declare class AutoICD {
|
|
|
209
209
|
/** Rate limit info from the most recent API response. */
|
|
210
210
|
lastRateLimit: RateLimit | null;
|
|
211
211
|
/** Sub-resource for ICD-10 code lookup. */
|
|
212
|
-
readonly
|
|
212
|
+
readonly icd10: ICD10Codes;
|
|
213
213
|
/** Sub-resource for ICD-11 code lookup. */
|
|
214
214
|
readonly icd11: ICD11Codes;
|
|
215
215
|
constructor(options: AutoICDOptions);
|
|
@@ -242,7 +242,7 @@ declare class AutoICD {
|
|
|
242
242
|
post<T>(path: string, body: Record<string, unknown>): Promise<T>;
|
|
243
243
|
private request;
|
|
244
244
|
}
|
|
245
|
-
declare class
|
|
245
|
+
declare class ICD10Codes {
|
|
246
246
|
private readonly client;
|
|
247
247
|
constructor(client: AutoICD);
|
|
248
248
|
/**
|
|
@@ -250,7 +250,7 @@ declare class Codes {
|
|
|
250
250
|
*
|
|
251
251
|
* @example
|
|
252
252
|
* ```ts
|
|
253
|
-
* const results = await autoicd.
|
|
253
|
+
* const results = await autoicd.icd10.search("diabetes mellitus");
|
|
254
254
|
* ```
|
|
255
255
|
*/
|
|
256
256
|
search(query: string, options?: SearchOptions): Promise<CodeSearchResponse>;
|
|
@@ -260,7 +260,7 @@ declare class Codes {
|
|
|
260
260
|
*
|
|
261
261
|
* @example
|
|
262
262
|
* ```ts
|
|
263
|
-
* const detail = await autoicd.
|
|
263
|
+
* const detail = await autoicd.icd10.get("E11.9");
|
|
264
264
|
* console.log(detail.long_description);
|
|
265
265
|
* console.log(detail.synonyms.snomed); // SNOMED CT synonyms
|
|
266
266
|
* console.log(detail.chapter?.title); // "Endocrine, Nutritional and Metabolic Diseases"
|
package/dist/index.js
CHANGED
|
@@ -69,7 +69,7 @@ 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
|
-
|
|
72
|
+
icd10;
|
|
73
73
|
/** Sub-resource for ICD-11 code lookup. */
|
|
74
74
|
icd11;
|
|
75
75
|
constructor(options) {
|
|
@@ -80,7 +80,7 @@ var AutoICD = class {
|
|
|
80
80
|
this.baseURL = (options.baseURL ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
81
81
|
this.timeout = options.timeout ?? DEFAULT_TIMEOUT;
|
|
82
82
|
this._fetch = options.fetch ?? globalThis.fetch;
|
|
83
|
-
this.
|
|
83
|
+
this.icd10 = new ICD10Codes(this);
|
|
84
84
|
this.icd11 = new ICD11Codes(this);
|
|
85
85
|
}
|
|
86
86
|
// ─── Public Methods ───
|
|
@@ -173,7 +173,7 @@ var AutoICD = class {
|
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
175
|
};
|
|
176
|
-
var
|
|
176
|
+
var ICD10Codes = class {
|
|
177
177
|
constructor(client) {
|
|
178
178
|
this.client = client;
|
|
179
179
|
}
|
|
@@ -182,14 +182,14 @@ var Codes = class {
|
|
|
182
182
|
*
|
|
183
183
|
* @example
|
|
184
184
|
* ```ts
|
|
185
|
-
* const results = await autoicd.
|
|
185
|
+
* const results = await autoicd.icd10.search("diabetes mellitus");
|
|
186
186
|
* ```
|
|
187
187
|
*/
|
|
188
188
|
async search(query, options) {
|
|
189
189
|
const params = new URLSearchParams({ q: query });
|
|
190
190
|
if (options?.limit !== void 0) params.set("limit", String(options.limit));
|
|
191
191
|
if (options?.offset !== void 0) params.set("offset", String(options.offset));
|
|
192
|
-
return this.client.get(`/api/v1/codes/search?${params}`);
|
|
192
|
+
return this.client.get(`/api/v1/icd10/codes/search?${params}`);
|
|
193
193
|
}
|
|
194
194
|
/**
|
|
195
195
|
* Get comprehensive details for a single ICD-10 code, including synonyms,
|
|
@@ -197,7 +197,7 @@ var Codes = class {
|
|
|
197
197
|
*
|
|
198
198
|
* @example
|
|
199
199
|
* ```ts
|
|
200
|
-
* const detail = await autoicd.
|
|
200
|
+
* const detail = await autoicd.icd10.get("E11.9");
|
|
201
201
|
* console.log(detail.long_description);
|
|
202
202
|
* console.log(detail.synonyms.snomed); // SNOMED CT synonyms
|
|
203
203
|
* console.log(detail.chapter?.title); // "Endocrine, Nutritional and Metabolic Diseases"
|
|
@@ -205,7 +205,7 @@ var Codes = class {
|
|
|
205
205
|
* ```
|
|
206
206
|
*/
|
|
207
207
|
async get(code) {
|
|
208
|
-
return this.client.get(`/api/v1/codes/${encodeURIComponent(code)}`);
|
|
208
|
+
return this.client.get(`/api/v1/icd10/codes/${encodeURIComponent(code)}`);
|
|
209
209
|
}
|
|
210
210
|
};
|
|
211
211
|
var ICD11Codes = class {
|
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} 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 icd10: ICD10Codes;\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.icd10 = new ICD10Codes(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// ─── 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// ─── 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,7 +39,7 @@ 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
|
-
|
|
42
|
+
icd10;
|
|
43
43
|
/** Sub-resource for ICD-11 code lookup. */
|
|
44
44
|
icd11;
|
|
45
45
|
constructor(options) {
|
|
@@ -50,7 +50,7 @@ var AutoICD = class {
|
|
|
50
50
|
this.baseURL = (options.baseURL ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
51
51
|
this.timeout = options.timeout ?? DEFAULT_TIMEOUT;
|
|
52
52
|
this._fetch = options.fetch ?? globalThis.fetch;
|
|
53
|
-
this.
|
|
53
|
+
this.icd10 = new ICD10Codes(this);
|
|
54
54
|
this.icd11 = new ICD11Codes(this);
|
|
55
55
|
}
|
|
56
56
|
// ─── Public Methods ───
|
|
@@ -143,7 +143,7 @@ var AutoICD = class {
|
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
};
|
|
146
|
-
var
|
|
146
|
+
var ICD10Codes = class {
|
|
147
147
|
constructor(client) {
|
|
148
148
|
this.client = client;
|
|
149
149
|
}
|
|
@@ -152,14 +152,14 @@ var Codes = class {
|
|
|
152
152
|
*
|
|
153
153
|
* @example
|
|
154
154
|
* ```ts
|
|
155
|
-
* const results = await autoicd.
|
|
155
|
+
* const results = await autoicd.icd10.search("diabetes mellitus");
|
|
156
156
|
* ```
|
|
157
157
|
*/
|
|
158
158
|
async search(query, options) {
|
|
159
159
|
const params = new URLSearchParams({ q: query });
|
|
160
160
|
if (options?.limit !== void 0) params.set("limit", String(options.limit));
|
|
161
161
|
if (options?.offset !== void 0) params.set("offset", String(options.offset));
|
|
162
|
-
return this.client.get(`/api/v1/codes/search?${params}`);
|
|
162
|
+
return this.client.get(`/api/v1/icd10/codes/search?${params}`);
|
|
163
163
|
}
|
|
164
164
|
/**
|
|
165
165
|
* Get comprehensive details for a single ICD-10 code, including synonyms,
|
|
@@ -167,7 +167,7 @@ var Codes = class {
|
|
|
167
167
|
*
|
|
168
168
|
* @example
|
|
169
169
|
* ```ts
|
|
170
|
-
* const detail = await autoicd.
|
|
170
|
+
* const detail = await autoicd.icd10.get("E11.9");
|
|
171
171
|
* console.log(detail.long_description);
|
|
172
172
|
* console.log(detail.synonyms.snomed); // SNOMED CT synonyms
|
|
173
173
|
* console.log(detail.chapter?.title); // "Endocrine, Nutritional and Metabolic Diseases"
|
|
@@ -175,7 +175,7 @@ var Codes = class {
|
|
|
175
175
|
* ```
|
|
176
176
|
*/
|
|
177
177
|
async get(code) {
|
|
178
|
-
return this.client.get(`/api/v1/codes/${encodeURIComponent(code)}`);
|
|
178
|
+
return this.client.get(`/api/v1/icd10/codes/${encodeURIComponent(code)}`);
|
|
179
179
|
}
|
|
180
180
|
};
|
|
181
181
|
var ICD11Codes = class {
|
package/dist/index.mjs.map
CHANGED
|
@@ -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} 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 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 }\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// ─── 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// ─── 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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "autoicd-js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
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.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|