@precisa-saude/fhir-ocr-utils 0.38.1 → 0.38.3
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/cli.js +22 -1
- package/dist/index.cjs +25 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -33,6 +33,9 @@ var UNAMBIGUOUS_SHORT_NAMES = /* @__PURE__ */ new Set([
|
|
|
33
33
|
"alt",
|
|
34
34
|
"ast",
|
|
35
35
|
"bun",
|
|
36
|
+
// Creatina quinase: Fleury e a Quest imprimem só "CK", e sem a sigla o
|
|
37
|
+
// modelo ficava sem âncora e encaixava o valor em outro exame (PRE-486).
|
|
38
|
+
"ck",
|
|
36
39
|
"wbc",
|
|
37
40
|
"rbc",
|
|
38
41
|
"mcv",
|
|
@@ -163,6 +166,9 @@ var GENETIC_CONTEXT_PATTERNS = [
|
|
|
163
166
|
/\bhomozigot/,
|
|
164
167
|
/\bsequence change\b/
|
|
165
168
|
];
|
|
169
|
+
var SUBTYPE_AFTER = {
|
|
170
|
+
CK: /^[\s-]*mb\b/i
|
|
171
|
+
};
|
|
166
172
|
|
|
167
173
|
// src/body-region.ts
|
|
168
174
|
var WHOLE_BODY_COMPOSITION_CODES = /* @__PURE__ */ new Set([
|
|
@@ -287,18 +293,30 @@ function mentionsUrinalysisHeader(normalizedText) {
|
|
|
287
293
|
return ANY_HEADER.test(normalizedText);
|
|
288
294
|
}
|
|
289
295
|
var URINALYSIS_SECTION_NAMES = /* @__PURE__ */ new Map([
|
|
296
|
+
// "Aspecto", "Densidade" e "Corpos Cetônicos" são as grafias dos laudos
|
|
297
|
+
// brasileiros, e "Leukocytes", "Erythrocytes" e "Eritrócitos" as do
|
|
298
|
+
// sedimento. Fora deste mapa, "Corpos Cetônicos" e "Leukocytes" casam
|
|
299
|
+
// exames de outro painel (o beta-hidroxibutirato, o leucograma), a linha
|
|
300
|
+
// conta como `foreign` e a seção acabava ali, levando junto todas as linhas
|
|
301
|
+
// de baixo, que voltavam para os códigos do sangue (PRE-486).
|
|
302
|
+
["aspecto", "Appearance_Urine"],
|
|
290
303
|
["bacteria", "Bacteria_Urine"],
|
|
291
304
|
["bacterias", "Bacteria_Urine"],
|
|
292
305
|
["bilirrubina", "Bilirubin_Urine"],
|
|
293
306
|
["bilirubin", "Bilirubin_Urine"],
|
|
294
307
|
["cetonas", "Ketones_Urine"],
|
|
295
308
|
["color", "Color_Urine"],
|
|
309
|
+
["corpos cetonicos", "Ketones_Urine"],
|
|
296
310
|
["cor", "Color_Urine"],
|
|
311
|
+
["densidade", "SpecificGravity_Urine"],
|
|
312
|
+
["eritrocitos", "RBC_Urine"],
|
|
313
|
+
["erythrocytes", "RBC_Urine"],
|
|
297
314
|
["glicose", "Glucose_Urine"],
|
|
298
315
|
["glucose", "Glucose_Urine"],
|
|
299
316
|
["hemacias", "RBC_Urine"],
|
|
300
317
|
["ketones", "Ketones_Urine"],
|
|
301
318
|
["leucocitos", "Leukocytes_Urine"],
|
|
319
|
+
["leukocytes", "Leukocytes_Urine"],
|
|
302
320
|
["nitrite", "Nitrite_Urine"],
|
|
303
321
|
["nitrito", "Nitrite_Urine"],
|
|
304
322
|
["ph", "pH_Urine"],
|
|
@@ -681,6 +699,9 @@ function findBiomarkersInText(ocrText) {
|
|
|
681
699
|
if (qualifiedByBodyRegion(entry.code, before) || followedByPercent(entry.code, after)) {
|
|
682
700
|
continue;
|
|
683
701
|
}
|
|
702
|
+
if (SUBTYPE_AFTER[entry.code]?.test(after)) {
|
|
703
|
+
continue;
|
|
704
|
+
}
|
|
684
705
|
if (girth && SKINFOLD_SITE_CODES.has(entry.code)) {
|
|
685
706
|
continue;
|
|
686
707
|
}
|
|
@@ -1239,7 +1260,7 @@ async function main() {
|
|
|
1239
1260
|
strict: false
|
|
1240
1261
|
});
|
|
1241
1262
|
if (values.version) {
|
|
1242
|
-
process.stdout.write(`${"0.38.
|
|
1263
|
+
process.stdout.write(`${"0.38.3"}
|
|
1243
1264
|
`);
|
|
1244
1265
|
return;
|
|
1245
1266
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -17,6 +17,9 @@ var UNAMBIGUOUS_SHORT_NAMES = /* @__PURE__ */ new Set([
|
|
|
17
17
|
"alt",
|
|
18
18
|
"ast",
|
|
19
19
|
"bun",
|
|
20
|
+
// Creatina quinase: Fleury e a Quest imprimem só "CK", e sem a sigla o
|
|
21
|
+
// modelo ficava sem âncora e encaixava o valor em outro exame (PRE-486).
|
|
22
|
+
"ck",
|
|
20
23
|
"wbc",
|
|
21
24
|
"rbc",
|
|
22
25
|
"mcv",
|
|
@@ -147,6 +150,9 @@ var GENETIC_CONTEXT_PATTERNS = [
|
|
|
147
150
|
/\bhomozigot/,
|
|
148
151
|
/\bsequence change\b/
|
|
149
152
|
];
|
|
153
|
+
var SUBTYPE_AFTER = {
|
|
154
|
+
CK: /^[\s-]*mb\b/i
|
|
155
|
+
};
|
|
150
156
|
|
|
151
157
|
// src/body-region.ts
|
|
152
158
|
var WHOLE_BODY_COMPOSITION_CODES = /* @__PURE__ */ new Set([
|
|
@@ -271,18 +277,30 @@ function mentionsUrinalysisHeader(normalizedText) {
|
|
|
271
277
|
return ANY_HEADER.test(normalizedText);
|
|
272
278
|
}
|
|
273
279
|
var URINALYSIS_SECTION_NAMES = /* @__PURE__ */ new Map([
|
|
280
|
+
// "Aspecto", "Densidade" e "Corpos Cetônicos" são as grafias dos laudos
|
|
281
|
+
// brasileiros, e "Leukocytes", "Erythrocytes" e "Eritrócitos" as do
|
|
282
|
+
// sedimento. Fora deste mapa, "Corpos Cetônicos" e "Leukocytes" casam
|
|
283
|
+
// exames de outro painel (o beta-hidroxibutirato, o leucograma), a linha
|
|
284
|
+
// conta como `foreign` e a seção acabava ali, levando junto todas as linhas
|
|
285
|
+
// de baixo, que voltavam para os códigos do sangue (PRE-486).
|
|
286
|
+
["aspecto", "Appearance_Urine"],
|
|
274
287
|
["bacteria", "Bacteria_Urine"],
|
|
275
288
|
["bacterias", "Bacteria_Urine"],
|
|
276
289
|
["bilirrubina", "Bilirubin_Urine"],
|
|
277
290
|
["bilirubin", "Bilirubin_Urine"],
|
|
278
291
|
["cetonas", "Ketones_Urine"],
|
|
279
292
|
["color", "Color_Urine"],
|
|
293
|
+
["corpos cetonicos", "Ketones_Urine"],
|
|
280
294
|
["cor", "Color_Urine"],
|
|
295
|
+
["densidade", "SpecificGravity_Urine"],
|
|
296
|
+
["eritrocitos", "RBC_Urine"],
|
|
297
|
+
["erythrocytes", "RBC_Urine"],
|
|
281
298
|
["glicose", "Glucose_Urine"],
|
|
282
299
|
["glucose", "Glucose_Urine"],
|
|
283
300
|
["hemacias", "RBC_Urine"],
|
|
284
301
|
["ketones", "Ketones_Urine"],
|
|
285
302
|
["leucocitos", "Leukocytes_Urine"],
|
|
303
|
+
["leukocytes", "Leukocytes_Urine"],
|
|
286
304
|
["nitrite", "Nitrite_Urine"],
|
|
287
305
|
["nitrito", "Nitrite_Urine"],
|
|
288
306
|
["ph", "pH_Urine"],
|
|
@@ -665,6 +683,9 @@ function findBiomarkersInText(ocrText) {
|
|
|
665
683
|
if (qualifiedByBodyRegion(entry.code, before) || followedByPercent(entry.code, after)) {
|
|
666
684
|
continue;
|
|
667
685
|
}
|
|
686
|
+
if (_optionalChain([SUBTYPE_AFTER, 'access', _7 => _7[entry.code], 'optionalAccess', _8 => _8.test, 'call', _9 => _9(after)])) {
|
|
687
|
+
continue;
|
|
688
|
+
}
|
|
668
689
|
if (girth && SKINFOLD_SITE_CODES.has(entry.code)) {
|
|
669
690
|
continue;
|
|
670
691
|
}
|
|
@@ -892,8 +913,8 @@ function allowedKeys(anchors) {
|
|
|
892
913
|
}
|
|
893
914
|
function withScannedMethod(biomarker, anchors) {
|
|
894
915
|
const code = biomarker.loinc ? _fhir.loincToCode.call(void 0, biomarker.loinc) : void 0;
|
|
895
|
-
if (!code || !_optionalChain([_fhir.getDefinitionByCode.call(void 0, code), 'optionalAccess',
|
|
896
|
-
const scanned = _optionalChain([anchors, 'access',
|
|
916
|
+
if (!code || !_optionalChain([_fhir.getDefinitionByCode.call(void 0, code), 'optionalAccess', _10 => _10.methodVariants, 'optionalAccess', _11 => _11.length])) return biomarker;
|
|
917
|
+
const scanned = _optionalChain([anchors, 'access', _12 => _12.matches, 'access', _13 => _13.find, 'call', _14 => _14((m) => m.code === code), 'optionalAccess', _15 => _15.methodLoinc]);
|
|
897
918
|
const loinc = _nullishCoalesce(scanned, () => ( _fhir.codeToLoinc.call(void 0, code)));
|
|
898
919
|
return loinc && loinc !== biomarker.loinc ? { ...biomarker, loinc } : biomarker;
|
|
899
920
|
}
|
|
@@ -983,7 +1004,7 @@ function buildPrompt(text, allowed) {
|
|
|
983
1004
|
}
|
|
984
1005
|
function stripFence(raw) {
|
|
985
1006
|
const fenced = /```(?:json)?\s*([\s\S]*?)```/.exec(raw);
|
|
986
|
-
return (_nullishCoalesce(_optionalChain([fenced, 'optionalAccess',
|
|
1007
|
+
return (_nullishCoalesce(_optionalChain([fenced, 'optionalAccess', _16 => _16[1]]), () => ( raw))).trim();
|
|
987
1008
|
}
|
|
988
1009
|
async function extractWithModel(text, options) {
|
|
989
1010
|
const { apiKey, baseUrl, headers = {}, model, responseFormat, timeoutMs = 3e5 } = options;
|
|
@@ -1023,7 +1044,7 @@ async function extractWithModel(text, options) {
|
|
|
1023
1044
|
throw new Error(`${String(response.status)} de ${baseUrl}: ${await response.text()}`);
|
|
1024
1045
|
}
|
|
1025
1046
|
const body = await response.json();
|
|
1026
|
-
const raw = _nullishCoalesce(_optionalChain([body, 'access',
|
|
1047
|
+
const raw = _nullishCoalesce(_optionalChain([body, 'access', _17 => _17.choices, 'optionalAccess', _18 => _18[0], 'optionalAccess', _19 => _19.message, 'optionalAccess', _20 => _20.content]), () => ( ""));
|
|
1027
1048
|
const tookMs = Date.now() - startedAt;
|
|
1028
1049
|
try {
|
|
1029
1050
|
return { payload: JSON.parse(stripFence(raw)), raw, tookMs };
|