@cosyte/synth 0.1.5 → 0.1.7
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/CHANGELOG.md +30 -0
- package/dist/astm/index.cjs +57 -19
- package/dist/astm/index.cjs.map +1 -1
- package/dist/astm/index.d.cts +7 -0
- package/dist/astm/index.d.ts +7 -0
- package/dist/astm/index.mjs +56 -19
- package/dist/astm/index.mjs.map +1 -1
- package/dist/ccda/index.cjs +76 -26
- package/dist/ccda/index.cjs.map +1 -1
- package/dist/ccda/index.d.cts +6 -0
- package/dist/ccda/index.d.ts +6 -0
- package/dist/ccda/index.mjs +63 -14
- package/dist/ccda/index.mjs.map +1 -1
- package/dist/deid/index.cjs +216 -125
- package/dist/deid/index.cjs.map +1 -1
- package/dist/deid/index.mjs +203 -113
- package/dist/deid/index.mjs.map +1 -1
- package/dist/fhir/index.cjs +146 -74
- package/dist/fhir/index.cjs.map +1 -1
- package/dist/fhir/index.d.cts +6 -0
- package/dist/fhir/index.d.ts +6 -0
- package/dist/fhir/index.mjs +145 -74
- package/dist/fhir/index.mjs.map +1 -1
- package/dist/hl7/index.cjs +53 -9
- package/dist/hl7/index.cjs.map +1 -1
- package/dist/hl7/index.d.cts +6 -0
- package/dist/hl7/index.d.ts +6 -0
- package/dist/hl7/index.mjs +52 -9
- package/dist/hl7/index.mjs.map +1 -1
- package/dist/index.cjs +1 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +1 -3
- package/dist/index.mjs.map +1 -1
- package/dist/ncpdp/index.cjs +76 -23
- package/dist/ncpdp/index.cjs.map +1 -1
- package/dist/ncpdp/index.d.cts +7 -0
- package/dist/ncpdp/index.d.ts +7 -0
- package/dist/ncpdp/index.mjs +75 -23
- package/dist/ncpdp/index.mjs.map +1 -1
- package/dist/x12/index.cjs +72 -23
- package/dist/x12/index.cjs.map +1 -1
- package/dist/x12/index.d.cts +8 -1
- package/dist/x12/index.d.ts +8 -1
- package/dist/x12/index.mjs +71 -23
- package/dist/x12/index.mjs.map +1 -1
- package/package.json +20 -15
package/dist/deid/index.cjs
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var x12$1 = require('@cosyte/deid/x12');
|
|
6
|
-
var ncpdp = require('@cosyte/deid/ncpdp');
|
|
7
|
-
var ccda$1 = require('@cosyte/deid/ccda');
|
|
8
|
-
var fhir = require('@cosyte/fhir');
|
|
9
|
-
var x12 = require('@cosyte/x12');
|
|
10
|
-
var ccda = require('@cosyte/ccda');
|
|
11
|
-
var telecom = require('@cosyte/ncpdp/telecom');
|
|
12
|
-
var hl7$1 = require('@cosyte/hl7');
|
|
13
|
-
var deid = require('@cosyte/deid');
|
|
3
|
+
var module$1 = require('module');
|
|
4
|
+
var url = require('url');
|
|
14
5
|
|
|
15
|
-
|
|
6
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
7
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
8
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
9
|
+
}) : x)(function(x) {
|
|
10
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
11
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
12
|
+
});
|
|
16
13
|
|
|
17
14
|
// src/rng/splitmix32.ts
|
|
18
15
|
function splitmix32(seed) {
|
|
@@ -452,6 +449,40 @@ var safe = Object.freeze({
|
|
|
452
449
|
npi,
|
|
453
450
|
dea
|
|
454
451
|
});
|
|
452
|
+
function defaultHost() {
|
|
453
|
+
if (typeof undefined !== "function") return { require: __require, resolve: void 0 };
|
|
454
|
+
return { require: module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))), resolve: (s) => undefined(s) };
|
|
455
|
+
}
|
|
456
|
+
function isRequireEsmRefusal(error) {
|
|
457
|
+
return error?.code === "ERR_REQUIRE_ESM";
|
|
458
|
+
}
|
|
459
|
+
function loadPeer(specifier, host) {
|
|
460
|
+
if (host.resolve === void 0) return host.require(specifier);
|
|
461
|
+
const entry = url.fileURLToPath(host.resolve(specifier));
|
|
462
|
+
try {
|
|
463
|
+
return host.require(entry);
|
|
464
|
+
} catch (error) {
|
|
465
|
+
if (!isRequireEsmRefusal(error)) throw error;
|
|
466
|
+
return host.require(specifier);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
function lazyPeer(specifier, host) {
|
|
470
|
+
let loaded;
|
|
471
|
+
return () => loaded ??= loadPeer(specifier, defaultHost());
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// src/peers.ts
|
|
475
|
+
var hl7Peer = lazyPeer("@cosyte/hl7");
|
|
476
|
+
var fhirPeer = lazyPeer("@cosyte/fhir");
|
|
477
|
+
var ccdaPeer = lazyPeer("@cosyte/ccda");
|
|
478
|
+
var x12Peer = lazyPeer("@cosyte/x12");
|
|
479
|
+
var ncpdpTelecomPeer = lazyPeer("@cosyte/ncpdp/telecom");
|
|
480
|
+
var deidPeer = lazyPeer("@cosyte/deid");
|
|
481
|
+
var deidHl7Peer = lazyPeer("@cosyte/deid/hl7");
|
|
482
|
+
var deidFhirPeer = lazyPeer("@cosyte/deid/fhir");
|
|
483
|
+
var deidX12Peer = lazyPeer("@cosyte/deid/x12");
|
|
484
|
+
var deidNcpdpPeer = lazyPeer("@cosyte/deid/ncpdp");
|
|
485
|
+
var deidCcdaPeer = lazyPeer("@cosyte/deid/ccda");
|
|
455
486
|
|
|
456
487
|
// src/hl7/common.ts
|
|
457
488
|
function seededTimestamp(rng) {
|
|
@@ -464,7 +495,7 @@ function seededTimestamp(rng) {
|
|
|
464
495
|
function mshScaffold(rng, type) {
|
|
465
496
|
const timestamp = seededTimestamp(rng);
|
|
466
497
|
const controlId = `SYNTH${rng.digits(10)}`;
|
|
467
|
-
const message =
|
|
498
|
+
const message = hl7Peer().buildMessage({
|
|
468
499
|
type,
|
|
469
500
|
sendingApp: "COSYTE-SYNTH",
|
|
470
501
|
sendingFacility: "SYNTH-FAC",
|
|
@@ -915,36 +946,36 @@ function prop(name2, value) {
|
|
|
915
946
|
return { name: name2, value };
|
|
916
947
|
}
|
|
917
948
|
function str(value) {
|
|
918
|
-
return
|
|
949
|
+
return fhirPeer().primitive(value);
|
|
919
950
|
}
|
|
920
951
|
function dec(raw) {
|
|
921
|
-
return
|
|
952
|
+
return fhirPeer().primitive(fhirPeer().decimal(raw));
|
|
922
953
|
}
|
|
923
954
|
function bool(value) {
|
|
924
|
-
return
|
|
955
|
+
return fhirPeer().primitive(value);
|
|
925
956
|
}
|
|
926
957
|
function coding(concept) {
|
|
927
|
-
return
|
|
958
|
+
return fhirPeer().complex([
|
|
928
959
|
prop("system", str(concept.system)),
|
|
929
960
|
prop("code", str(concept.code)),
|
|
930
961
|
prop("display", str(concept.display))
|
|
931
962
|
]);
|
|
932
963
|
}
|
|
933
964
|
function codeableConcept(concept) {
|
|
934
|
-
return
|
|
965
|
+
return fhirPeer().complex([prop("coding", fhirPeer().list([coding(concept)]))]);
|
|
935
966
|
}
|
|
936
967
|
function reference(ref) {
|
|
937
|
-
return
|
|
968
|
+
return fhirPeer().complex([prop("reference", str(ref))]);
|
|
938
969
|
}
|
|
939
970
|
function narrative(text) {
|
|
940
971
|
const escaped = text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
941
|
-
return
|
|
972
|
+
return fhirPeer().complex([
|
|
942
973
|
prop("status", str("generated")),
|
|
943
974
|
prop("div", str(`<div xmlns="http://www.w3.org/1999/xhtml"><p>${escaped}</p></div>`))
|
|
944
975
|
]);
|
|
945
976
|
}
|
|
946
977
|
function meta(profiles) {
|
|
947
|
-
return
|
|
978
|
+
return fhirPeer().complex([prop("profile", fhirPeer().list(profiles.map((p) => str(p))))]);
|
|
948
979
|
}
|
|
949
980
|
function toFhirDate(ymd) {
|
|
950
981
|
return `${ymd.slice(0, 4)}-${ymd.slice(4, 6)}-${ymd.slice(6, 8)}`;
|
|
@@ -961,13 +992,13 @@ function fhirPatientIdentity(rng) {
|
|
|
961
992
|
return { id, person, mrn, birthDate, gender, address: address2, phone: phone2, email: email2 };
|
|
962
993
|
}
|
|
963
994
|
function mrnIdentifier(mrn) {
|
|
964
|
-
return
|
|
995
|
+
return fhirPeer().complex([
|
|
965
996
|
prop(
|
|
966
997
|
"type",
|
|
967
|
-
|
|
998
|
+
fhirPeer().complex([
|
|
968
999
|
prop(
|
|
969
1000
|
"coding",
|
|
970
|
-
|
|
1001
|
+
fhirPeer().list([
|
|
971
1002
|
coding({
|
|
972
1003
|
system: SYSTEM.IDENTIFIER_TYPE,
|
|
973
1004
|
code: "MR",
|
|
@@ -1252,13 +1283,16 @@ var EXAMPLE_ENCOUNTER_CLASSES = Object.freeze([
|
|
|
1252
1283
|
// src/fhir/patient.ts
|
|
1253
1284
|
var PATIENT_PROFILES = Object.freeze(["base", "us-core"]);
|
|
1254
1285
|
function ombExtension(url, category) {
|
|
1255
|
-
return
|
|
1286
|
+
return fhirPeer().complex([
|
|
1256
1287
|
prop("url", str(url)),
|
|
1257
1288
|
prop(
|
|
1258
1289
|
"extension",
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1290
|
+
fhirPeer().list([
|
|
1291
|
+
fhirPeer().complex([
|
|
1292
|
+
prop("url", str("ombCategory")),
|
|
1293
|
+
prop("valueCoding", coding(category))
|
|
1294
|
+
]),
|
|
1295
|
+
fhirPeer().complex([prop("url", str("text")), prop("valueString", str(category.display))])
|
|
1262
1296
|
])
|
|
1263
1297
|
)
|
|
1264
1298
|
]);
|
|
@@ -1289,24 +1323,27 @@ function generatePatient(options = {}) {
|
|
|
1289
1323
|
props.push(
|
|
1290
1324
|
prop(
|
|
1291
1325
|
"extension",
|
|
1292
|
-
|
|
1326
|
+
fhirPeer().list([
|
|
1293
1327
|
ombExtension(US_CORE_RACE_EXTENSION, race),
|
|
1294
1328
|
ombExtension(US_CORE_ETHNICITY_EXTENSION, ethnicity),
|
|
1295
|
-
|
|
1329
|
+
fhirPeer().complex([
|
|
1330
|
+
prop("url", str(US_CORE_BIRTHSEX_EXTENSION)),
|
|
1331
|
+
prop("valueCode", str(birthsex))
|
|
1332
|
+
])
|
|
1296
1333
|
])
|
|
1297
1334
|
)
|
|
1298
1335
|
);
|
|
1299
1336
|
}
|
|
1300
|
-
props.push(prop("identifier",
|
|
1337
|
+
props.push(prop("identifier", fhirPeer().list([mrnIdentifier(id.mrn)])));
|
|
1301
1338
|
props.push(prop("active", bool(true)));
|
|
1302
1339
|
props.push(
|
|
1303
1340
|
prop(
|
|
1304
1341
|
"name",
|
|
1305
|
-
|
|
1306
|
-
|
|
1342
|
+
fhirPeer().list([
|
|
1343
|
+
fhirPeer().complex([
|
|
1307
1344
|
prop("use", str("official")),
|
|
1308
1345
|
prop("family", str(id.person.family)),
|
|
1309
|
-
prop("given",
|
|
1346
|
+
prop("given", fhirPeer().list([str(id.person.given)]))
|
|
1310
1347
|
])
|
|
1311
1348
|
])
|
|
1312
1349
|
)
|
|
@@ -1314,13 +1351,13 @@ function generatePatient(options = {}) {
|
|
|
1314
1351
|
props.push(
|
|
1315
1352
|
prop(
|
|
1316
1353
|
"telecom",
|
|
1317
|
-
|
|
1318
|
-
|
|
1354
|
+
fhirPeer().list([
|
|
1355
|
+
fhirPeer().complex([
|
|
1319
1356
|
prop("system", str("phone")),
|
|
1320
1357
|
prop("value", str(id.phone)),
|
|
1321
1358
|
prop("use", str("home"))
|
|
1322
1359
|
]),
|
|
1323
|
-
|
|
1360
|
+
fhirPeer().complex([prop("system", str("email")), prop("value", str(id.email))])
|
|
1324
1361
|
])
|
|
1325
1362
|
)
|
|
1326
1363
|
);
|
|
@@ -1329,10 +1366,10 @@ function generatePatient(options = {}) {
|
|
|
1329
1366
|
props.push(
|
|
1330
1367
|
prop(
|
|
1331
1368
|
"address",
|
|
1332
|
-
|
|
1333
|
-
|
|
1369
|
+
fhirPeer().list([
|
|
1370
|
+
fhirPeer().complex([
|
|
1334
1371
|
prop("use", str("home")),
|
|
1335
|
-
prop("line",
|
|
1372
|
+
prop("line", fhirPeer().list([str(id.address.street)])),
|
|
1336
1373
|
prop("city", str(id.address.city)),
|
|
1337
1374
|
prop("state", str(id.address.state)),
|
|
1338
1375
|
prop("postalCode", str(id.address.zip))
|
|
@@ -1340,8 +1377,10 @@ function generatePatient(options = {}) {
|
|
|
1340
1377
|
])
|
|
1341
1378
|
)
|
|
1342
1379
|
);
|
|
1343
|
-
return
|
|
1380
|
+
return fhirPeer().complex(props);
|
|
1344
1381
|
}
|
|
1382
|
+
|
|
1383
|
+
// src/fhir/condition.ts
|
|
1345
1384
|
function generateCondition(options = {}) {
|
|
1346
1385
|
const { seed = 0, subject = "Patient/syn-patient-1", usCore = true } = options;
|
|
1347
1386
|
const rng = createRng(seed);
|
|
@@ -1371,7 +1410,7 @@ function generateCondition(options = {}) {
|
|
|
1371
1410
|
props.push(
|
|
1372
1411
|
prop(
|
|
1373
1412
|
"category",
|
|
1374
|
-
|
|
1413
|
+
fhirPeer().list([
|
|
1375
1414
|
codeableConcept({
|
|
1376
1415
|
system: SYSTEM.CONDITION_CATEGORY,
|
|
1377
1416
|
code: "problem-list-item",
|
|
@@ -1382,15 +1421,17 @@ function generateCondition(options = {}) {
|
|
|
1382
1421
|
);
|
|
1383
1422
|
props.push(prop("code", codeableConcept(code)));
|
|
1384
1423
|
props.push(prop("subject", reference(subject)));
|
|
1385
|
-
return
|
|
1424
|
+
return fhirPeer().complex(props);
|
|
1386
1425
|
}
|
|
1426
|
+
|
|
1427
|
+
// src/fhir/observation.ts
|
|
1387
1428
|
function drawValue(rng, concept) {
|
|
1388
1429
|
const span = concept.high - concept.low;
|
|
1389
1430
|
const raw = concept.low + rng.float() * span;
|
|
1390
1431
|
return raw.toFixed(concept.decimals);
|
|
1391
1432
|
}
|
|
1392
1433
|
function valueQuantity(rng, concept) {
|
|
1393
|
-
return
|
|
1434
|
+
return fhirPeer().complex([
|
|
1394
1435
|
prop("value", dec(drawValue(rng, concept))),
|
|
1395
1436
|
prop("unit", str(concept.unit)),
|
|
1396
1437
|
prop("system", str(SYSTEM.UCUM)),
|
|
@@ -1412,7 +1453,7 @@ function buildObservation(seed, subject, usCore, profileUrl, category, pool, eff
|
|
|
1412
1453
|
props.push(
|
|
1413
1454
|
prop(
|
|
1414
1455
|
"category",
|
|
1415
|
-
|
|
1456
|
+
fhirPeer().list([
|
|
1416
1457
|
codeableConcept({
|
|
1417
1458
|
system: SYSTEM.OBSERVATION_CATEGORY,
|
|
1418
1459
|
code: category.code,
|
|
@@ -1428,7 +1469,7 @@ function buildObservation(seed, subject, usCore, profileUrl, category, pool, eff
|
|
|
1428
1469
|
const d = String(rng.int(1, 28)).padStart(2, "0");
|
|
1429
1470
|
if (effective) props.push(prop("effectiveDateTime", str(`${String(y)}-${m}-${d}`)));
|
|
1430
1471
|
props.push(prop("valueQuantity", valueQuantity(rng, concept)));
|
|
1431
|
-
return
|
|
1472
|
+
return fhirPeer().complex(props);
|
|
1432
1473
|
}
|
|
1433
1474
|
function generateObservationLab(options = {}) {
|
|
1434
1475
|
const { seed = 0, subject = "Patient/syn-patient-1", usCore = true } = options;
|
|
@@ -1454,6 +1495,8 @@ function generateVitalSign(options = {}) {
|
|
|
1454
1495
|
true
|
|
1455
1496
|
);
|
|
1456
1497
|
}
|
|
1498
|
+
|
|
1499
|
+
// src/fhir/medication-request.ts
|
|
1457
1500
|
function generateMedicationRequest(options = {}) {
|
|
1458
1501
|
const {
|
|
1459
1502
|
seed = 0,
|
|
@@ -1478,8 +1521,10 @@ function generateMedicationRequest(options = {}) {
|
|
|
1478
1521
|
props.push(prop("subject", reference(subject)));
|
|
1479
1522
|
props.push(prop("authoredOn", str(`${String(y)}-${m}-${d}`)));
|
|
1480
1523
|
props.push(prop("requester", reference(requester)));
|
|
1481
|
-
return
|
|
1524
|
+
return fhirPeer().complex(props);
|
|
1482
1525
|
}
|
|
1526
|
+
|
|
1527
|
+
// src/fhir/encounter.ts
|
|
1483
1528
|
function generateEncounter(options = {}) {
|
|
1484
1529
|
const { seed = 0, subject = "Patient/syn-patient-1", usCore = true } = options;
|
|
1485
1530
|
const rng = createRng(seed);
|
|
@@ -1496,8 +1541,8 @@ function generateEncounter(options = {}) {
|
|
|
1496
1541
|
props.push(
|
|
1497
1542
|
prop(
|
|
1498
1543
|
"identifier",
|
|
1499
|
-
|
|
1500
|
-
|
|
1544
|
+
fhirPeer().list([
|
|
1545
|
+
fhirPeer().complex([
|
|
1501
1546
|
prop("system", str(`urn:oid:${id.assigningAuthorityOid}`)),
|
|
1502
1547
|
prop("value", str(id.value))
|
|
1503
1548
|
])
|
|
@@ -1506,11 +1551,13 @@ function generateEncounter(options = {}) {
|
|
|
1506
1551
|
);
|
|
1507
1552
|
props.push(prop("status", str("finished")));
|
|
1508
1553
|
props.push(prop("class", coding(cls)));
|
|
1509
|
-
props.push(prop("type",
|
|
1554
|
+
props.push(prop("type", fhirPeer().list([codeableConcept(type)])));
|
|
1510
1555
|
props.push(prop("subject", reference(subject)));
|
|
1511
|
-
props.push(prop("period",
|
|
1512
|
-
return
|
|
1556
|
+
props.push(prop("period", fhirPeer().complex([prop("start", str(`${start}T09:00:00Z`))])));
|
|
1557
|
+
return fhirPeer().complex(props);
|
|
1513
1558
|
}
|
|
1559
|
+
|
|
1560
|
+
// src/fhir/immunization.ts
|
|
1514
1561
|
function generateImmunization(options = {}) {
|
|
1515
1562
|
const { seed = 0, patient = "Patient/syn-patient-1", usCore = true } = options;
|
|
1516
1563
|
const rng = createRng(seed);
|
|
@@ -1527,8 +1574,10 @@ function generateImmunization(options = {}) {
|
|
|
1527
1574
|
props.push(prop("patient", reference(patient)));
|
|
1528
1575
|
props.push(prop("occurrenceDateTime", str(occurrence)));
|
|
1529
1576
|
props.push(prop("primarySource", bool(true)));
|
|
1530
|
-
return
|
|
1577
|
+
return fhirPeer().complex(props);
|
|
1531
1578
|
}
|
|
1579
|
+
|
|
1580
|
+
// src/fhir/allergy-intolerance.ts
|
|
1532
1581
|
function generateAllergyIntolerance(options = {}) {
|
|
1533
1582
|
const { seed = 0, patient = "Patient/syn-patient-1", usCore = true } = options;
|
|
1534
1583
|
const rng = createRng(seed);
|
|
@@ -1561,11 +1610,17 @@ function generateAllergyIntolerance(options = {}) {
|
|
|
1561
1610
|
props.push(
|
|
1562
1611
|
prop(
|
|
1563
1612
|
"reaction",
|
|
1564
|
-
|
|
1613
|
+
fhirPeer().list([
|
|
1614
|
+
fhirPeer().complex([
|
|
1615
|
+
prop("manifestation", fhirPeer().list([codeableConcept(manifestation)]))
|
|
1616
|
+
])
|
|
1617
|
+
])
|
|
1565
1618
|
)
|
|
1566
1619
|
);
|
|
1567
|
-
return
|
|
1620
|
+
return fhirPeer().complex(props);
|
|
1568
1621
|
}
|
|
1622
|
+
|
|
1623
|
+
// src/fhir/procedure.ts
|
|
1569
1624
|
function generateProcedure(options = {}) {
|
|
1570
1625
|
const { seed = 0, subject = "Patient/syn-patient-1", usCore = true } = options;
|
|
1571
1626
|
const rng = createRng(seed);
|
|
@@ -1581,8 +1636,10 @@ function generateProcedure(options = {}) {
|
|
|
1581
1636
|
props.push(prop("code", codeableConcept(code)));
|
|
1582
1637
|
props.push(prop("subject", reference(subject)));
|
|
1583
1638
|
props.push(prop("performedDateTime", str(`${performed}T10:00:00Z`)));
|
|
1584
|
-
return
|
|
1639
|
+
return fhirPeer().complex(props);
|
|
1585
1640
|
}
|
|
1641
|
+
|
|
1642
|
+
// src/fhir/diagnostic-report.ts
|
|
1586
1643
|
function generateDiagnosticReport(options = {}) {
|
|
1587
1644
|
const { seed = 0, subject = "Patient/syn-patient-1", results = [], usCore = true } = options;
|
|
1588
1645
|
const rng = createRng(seed);
|
|
@@ -1598,7 +1655,7 @@ function generateDiagnosticReport(options = {}) {
|
|
|
1598
1655
|
props.push(
|
|
1599
1656
|
prop(
|
|
1600
1657
|
"category",
|
|
1601
|
-
|
|
1658
|
+
fhirPeer().list([
|
|
1602
1659
|
codeableConcept({
|
|
1603
1660
|
system: SYSTEM.DIAGNOSTIC_SERVICE_SECTION,
|
|
1604
1661
|
code: "LAB",
|
|
@@ -1612,15 +1669,17 @@ function generateDiagnosticReport(options = {}) {
|
|
|
1612
1669
|
props.push(prop("effectiveDateTime", str(`${day}T08:30:00Z`)));
|
|
1613
1670
|
props.push(prop("issued", str(`${day}T09:00:00.000Z`)));
|
|
1614
1671
|
if (results.length > 0) {
|
|
1615
|
-
props.push(prop("result",
|
|
1672
|
+
props.push(prop("result", fhirPeer().list(results.map((r) => reference(r)))));
|
|
1616
1673
|
}
|
|
1617
|
-
return
|
|
1674
|
+
return fhirPeer().complex(props);
|
|
1618
1675
|
}
|
|
1676
|
+
|
|
1677
|
+
// src/fhir/composition.ts
|
|
1619
1678
|
function section(sec) {
|
|
1620
|
-
return
|
|
1679
|
+
return fhirPeer().complex([
|
|
1621
1680
|
prop("title", str(sec.title)),
|
|
1622
1681
|
prop("code", codeableConcept({ system: SYSTEM.LOINC, code: sec.code, display: sec.title })),
|
|
1623
|
-
prop("entry",
|
|
1682
|
+
prop("entry", fhirPeer().list(sec.entries.map((e) => reference(e))))
|
|
1624
1683
|
]);
|
|
1625
1684
|
}
|
|
1626
1685
|
function buildComposition(rng, input) {
|
|
@@ -1639,12 +1698,12 @@ function buildComposition(rng, input) {
|
|
|
1639
1698
|
),
|
|
1640
1699
|
prop("subject", reference(input.subject)),
|
|
1641
1700
|
prop("date", str(`${input.date}T09:00:00Z`)),
|
|
1642
|
-
prop("author",
|
|
1701
|
+
prop("author", fhirPeer().list([reference(input.organization)])),
|
|
1643
1702
|
prop("title", str("Synthetic Continuity of Care Document")),
|
|
1644
1703
|
prop("custodian", reference(input.organization)),
|
|
1645
|
-
prop("section",
|
|
1704
|
+
prop("section", fhirPeer().list(input.sections.map((s) => section(s))))
|
|
1646
1705
|
];
|
|
1647
|
-
return
|
|
1706
|
+
return fhirPeer().complex(props);
|
|
1648
1707
|
}
|
|
1649
1708
|
|
|
1650
1709
|
// src/fhir/bundle.ts
|
|
@@ -1659,14 +1718,14 @@ function resourceTypeOf(resource) {
|
|
|
1659
1718
|
}
|
|
1660
1719
|
function buildOrganization(rng) {
|
|
1661
1720
|
const id = safe.identifier(rng, "AN");
|
|
1662
|
-
return
|
|
1721
|
+
return fhirPeer().complex([
|
|
1663
1722
|
prop("resourceType", str("Organization")),
|
|
1664
1723
|
prop("id", str(`syn-org-${rng.digits(8)}`)),
|
|
1665
1724
|
prop("text", narrative("Synthetic health organization.")),
|
|
1666
1725
|
prop(
|
|
1667
1726
|
"identifier",
|
|
1668
|
-
|
|
1669
|
-
|
|
1727
|
+
fhirPeer().list([
|
|
1728
|
+
fhirPeer().complex([
|
|
1670
1729
|
prop("system", str(`urn:oid:${id.assigningAuthorityOid}`)),
|
|
1671
1730
|
prop("value", str(id.value))
|
|
1672
1731
|
])
|
|
@@ -1779,11 +1838,14 @@ function generateBundle(options = {}) {
|
|
|
1779
1838
|
entryProps.push(
|
|
1780
1839
|
prop(
|
|
1781
1840
|
"request",
|
|
1782
|
-
|
|
1841
|
+
fhirPeer().complex([
|
|
1842
|
+
prop("method", str("POST")),
|
|
1843
|
+
prop("url", str(resourceTypeOf(member.resource)))
|
|
1844
|
+
])
|
|
1783
1845
|
)
|
|
1784
1846
|
);
|
|
1785
1847
|
}
|
|
1786
|
-
return
|
|
1848
|
+
return fhirPeer().complex(entryProps);
|
|
1787
1849
|
});
|
|
1788
1850
|
const props = [
|
|
1789
1851
|
prop("resourceType", str("Bundle")),
|
|
@@ -1794,7 +1856,7 @@ function generateBundle(options = {}) {
|
|
|
1794
1856
|
props.push(
|
|
1795
1857
|
prop(
|
|
1796
1858
|
"identifier",
|
|
1797
|
-
|
|
1859
|
+
fhirPeer().complex([
|
|
1798
1860
|
prop("system", str(`urn:oid:${id.assigningAuthorityOid}`)),
|
|
1799
1861
|
prop("value", str(`urn:uuid:${safe.uuid(rng)}`))
|
|
1800
1862
|
])
|
|
@@ -1803,11 +1865,13 @@ function generateBundle(options = {}) {
|
|
|
1803
1865
|
}
|
|
1804
1866
|
props.push(prop("type", str(type)));
|
|
1805
1867
|
if (type === "document") props.push(prop("timestamp", str(`${spine.date}T09:00:00.000Z`)));
|
|
1806
|
-
props.push(prop("entry",
|
|
1807
|
-
return
|
|
1868
|
+
props.push(prop("entry", fhirPeer().list(entries)));
|
|
1869
|
+
return fhirPeer().complex(props);
|
|
1808
1870
|
}
|
|
1871
|
+
|
|
1872
|
+
// src/x12/money.ts
|
|
1809
1873
|
function dec2(value) {
|
|
1810
|
-
const d =
|
|
1874
|
+
const d = x12Peer().X12Decimal.fromString(value);
|
|
1811
1875
|
if (d === void 0) throw new SynthError(SYNTH_FATAL_CODES.SYNTH_INVALID_DECIMAL);
|
|
1812
1876
|
return d;
|
|
1813
1877
|
}
|
|
@@ -1890,12 +1954,12 @@ var PROCEDURE_MODIFIERS = Object.freeze(["25", "59", "76", "GT"]);
|
|
|
1890
1954
|
var PLACES_OF_SERVICE = Object.freeze(["11", "22", "21", "12", "49"]);
|
|
1891
1955
|
var DIAGNOSES = Object.freeze(
|
|
1892
1956
|
[
|
|
1893
|
-
{ code: "
|
|
1894
|
-
{ code: "
|
|
1957
|
+
{ code: "J209", label: "acute bronchitis, unspecified" },
|
|
1958
|
+
{ code: "E119", label: "type 2 diabetes mellitus without complications" },
|
|
1895
1959
|
{ code: "I10", label: "essential (primary) hypertension" },
|
|
1896
|
-
{ code: "
|
|
1897
|
-
{ code: "
|
|
1898
|
-
{ code: "
|
|
1960
|
+
{ code: "M545", label: "low back pain" },
|
|
1961
|
+
{ code: "R079", label: "chest pain, unspecified" },
|
|
1962
|
+
{ code: "Z0000", label: "general adult medical exam without abnormal findings" }
|
|
1899
1963
|
].map((entry) => Object.freeze(entry))
|
|
1900
1964
|
);
|
|
1901
1965
|
var REVENUE_CODES = Object.freeze(
|
|
@@ -2112,11 +2176,11 @@ function generate837(variant, options) {
|
|
|
2112
2176
|
const spec = specOf(rng, resolved);
|
|
2113
2177
|
switch (resolved) {
|
|
2114
2178
|
case "P":
|
|
2115
|
-
return
|
|
2179
|
+
return x12Peer().build837P(spec);
|
|
2116
2180
|
case "I":
|
|
2117
|
-
return
|
|
2181
|
+
return x12Peer().build837I(spec);
|
|
2118
2182
|
case "D":
|
|
2119
|
-
return
|
|
2183
|
+
return x12Peer().build837D(spec);
|
|
2120
2184
|
}
|
|
2121
2185
|
}
|
|
2122
2186
|
function generate837P(options) {
|
|
@@ -2128,6 +2192,8 @@ function generate837I(options) {
|
|
|
2128
2192
|
function generate837D(options) {
|
|
2129
2193
|
return generate837("D", options);
|
|
2130
2194
|
}
|
|
2195
|
+
|
|
2196
|
+
// src/x12/remit-835.ts
|
|
2131
2197
|
function generate835(options) {
|
|
2132
2198
|
const rng = createRng(options.seed);
|
|
2133
2199
|
const partners = x12TradingPartners(rng);
|
|
@@ -2228,8 +2294,10 @@ function generate835(options) {
|
|
|
2228
2294
|
},
|
|
2229
2295
|
claims: [claim]
|
|
2230
2296
|
};
|
|
2231
|
-
return
|
|
2297
|
+
return x12Peer().build835(spec);
|
|
2232
2298
|
}
|
|
2299
|
+
|
|
2300
|
+
// src/x12/eligibility-271.ts
|
|
2233
2301
|
function generate271(options) {
|
|
2234
2302
|
const rng = createRng(options.seed);
|
|
2235
2303
|
const partners = x12TradingPartners(rng);
|
|
@@ -2299,7 +2367,8 @@ function generate271(options) {
|
|
|
2299
2367
|
serviceTypeCodes: serviceTypes,
|
|
2300
2368
|
inPlanNetwork: "Y",
|
|
2301
2369
|
monetaryAmount: dec2(money(rng.int(500, 5e3))),
|
|
2302
|
-
percent: dec2(
|
|
2370
|
+
percent: dec2(rng.pick([".8", ".9", "1"]))
|
|
2371
|
+
// EB-08 is a decimal fraction
|
|
2303
2372
|
}
|
|
2304
2373
|
]
|
|
2305
2374
|
}
|
|
@@ -2309,7 +2378,7 @@ function generate271(options) {
|
|
|
2309
2378
|
}
|
|
2310
2379
|
]
|
|
2311
2380
|
};
|
|
2312
|
-
return
|
|
2381
|
+
return x12Peer().build271(spec);
|
|
2313
2382
|
}
|
|
2314
2383
|
|
|
2315
2384
|
// src/ncpdp/identity.ts
|
|
@@ -2365,6 +2434,8 @@ var EXAMPLE_DRUGS = Object.freeze(
|
|
|
2365
2434
|
].map((entry) => Object.freeze(entry))
|
|
2366
2435
|
);
|
|
2367
2436
|
var DAW_CODES = Object.freeze(["0", "1", "2"]);
|
|
2437
|
+
|
|
2438
|
+
// src/ncpdp/telecom.ts
|
|
2368
2439
|
var SYNTHETIC_BIN = "999999";
|
|
2369
2440
|
function digitsOnly(value) {
|
|
2370
2441
|
return value.replace(/\D/g, "");
|
|
@@ -2448,7 +2519,8 @@ function claimSegment(rng, minimal) {
|
|
|
2448
2519
|
field("E1", "03"),
|
|
2449
2520
|
// 03 = NDC
|
|
2450
2521
|
field("D7", drug.ndc),
|
|
2451
|
-
field("E7", String(rng.int(30, 90))),
|
|
2522
|
+
field("E7", String(rng.int(30, 90) * 1e3)),
|
|
2523
|
+
// 442-E7 carries three implied decimals
|
|
2452
2524
|
field("D5", String(rng.pick([30, 60, 90]))),
|
|
2453
2525
|
field("D8", rng.pick(DAW_CODES))
|
|
2454
2526
|
]
|
|
@@ -2464,7 +2536,9 @@ function generateTelecom(code, options) {
|
|
|
2464
2536
|
prescriberSegment(rng),
|
|
2465
2537
|
claimSegment(rng, false)
|
|
2466
2538
|
];
|
|
2467
|
-
return
|
|
2539
|
+
return ncpdpTelecomPeer().serializeTelecom(
|
|
2540
|
+
ncpdpTelecomPeer().buildTelecomRequest({ header: head, segments })
|
|
2541
|
+
);
|
|
2468
2542
|
}
|
|
2469
2543
|
function generateB1(options) {
|
|
2470
2544
|
return generateTelecom("B1", options);
|
|
@@ -2475,11 +2549,23 @@ function generateB2(options) {
|
|
|
2475
2549
|
function generateB3(options) {
|
|
2476
2550
|
return generateTelecom("B3", options);
|
|
2477
2551
|
}
|
|
2552
|
+
|
|
2553
|
+
// src/ccda/example-codes.ts
|
|
2554
|
+
var LOINC_OID = "2.16.840.1.113883.6.1";
|
|
2555
|
+
var SNOMED_CT_OID = "2.16.840.1.113883.6.96";
|
|
2556
|
+
var RXNORM_OID = "2.16.840.1.113883.6.88";
|
|
2557
|
+
var CVX_OID = "2.16.840.1.113883.12.292";
|
|
2558
|
+
var NCI_ROUTE_OID = "2.16.840.1.113883.3.26.1.1";
|
|
2559
|
+
var LOINC = LOINC_OID;
|
|
2560
|
+
var SNOMED_CT = SNOMED_CT_OID;
|
|
2561
|
+
var RXNORM = RXNORM_OID;
|
|
2562
|
+
var CVX = CVX_OID;
|
|
2563
|
+
var NCI_ROUTE = NCI_ROUTE_OID;
|
|
2478
2564
|
var URI_TO_OID = Object.freeze({
|
|
2479
|
-
"http://loinc.org":
|
|
2480
|
-
"http://snomed.info/sct":
|
|
2481
|
-
"http://www.nlm.nih.gov/research/umls/rxnorm":
|
|
2482
|
-
"http://hl7.org/fhir/sid/cvx":
|
|
2565
|
+
"http://loinc.org": LOINC,
|
|
2566
|
+
"http://snomed.info/sct": SNOMED_CT,
|
|
2567
|
+
"http://www.nlm.nih.gov/research/umls/rxnorm": RXNORM,
|
|
2568
|
+
"http://hl7.org/fhir/sid/cvx": CVX
|
|
2483
2569
|
});
|
|
2484
2570
|
function toBuildCode(concept) {
|
|
2485
2571
|
const codeSystem = URI_TO_OID[concept.system];
|
|
@@ -2503,24 +2589,24 @@ var VITAL_SIGNS = EXAMPLE_VITAL_SIGNS;
|
|
|
2503
2589
|
var VACCINES = EXAMPLE_VACCINES2;
|
|
2504
2590
|
var PROCEDURES = EXAMPLE_PROCEDURES;
|
|
2505
2591
|
var SMOKING_STATUSES = Object.freeze([
|
|
2506
|
-
Object.freeze({ code: "266919005", codeSystem:
|
|
2507
|
-
Object.freeze({ code: "8517006", codeSystem:
|
|
2592
|
+
Object.freeze({ code: "266919005", codeSystem: SNOMED_CT, displayName: "Never smoker" }),
|
|
2593
|
+
Object.freeze({ code: "8517006", codeSystem: SNOMED_CT, displayName: "Former smoker" }),
|
|
2508
2594
|
Object.freeze({
|
|
2509
2595
|
code: "449868002",
|
|
2510
|
-
codeSystem:
|
|
2596
|
+
codeSystem: SNOMED_CT,
|
|
2511
2597
|
displayName: "Current every day smoker"
|
|
2512
2598
|
}),
|
|
2513
2599
|
Object.freeze({
|
|
2514
2600
|
code: "428041000124106",
|
|
2515
|
-
codeSystem:
|
|
2601
|
+
codeSystem: SNOMED_CT,
|
|
2516
2602
|
displayName: "Current some day smoker"
|
|
2517
2603
|
})
|
|
2518
2604
|
]);
|
|
2519
2605
|
var ROUTES = Object.freeze([
|
|
2520
|
-
Object.freeze({ code: "C38288", codeSystem:
|
|
2521
|
-
Object.freeze({ code: "C28161", codeSystem:
|
|
2522
|
-
Object.freeze({ code: "C38276", codeSystem:
|
|
2523
|
-
Object.freeze({ code: "C38299", codeSystem:
|
|
2606
|
+
Object.freeze({ code: "C38288", codeSystem: NCI_ROUTE, displayName: "Oral" }),
|
|
2607
|
+
Object.freeze({ code: "C28161", codeSystem: NCI_ROUTE, displayName: "Intramuscular" }),
|
|
2608
|
+
Object.freeze({ code: "C38276", codeSystem: NCI_ROUTE, displayName: "Intravenous" }),
|
|
2609
|
+
Object.freeze({ code: "C38299", codeSystem: NCI_ROUTE, displayName: "Subcutaneous" })
|
|
2524
2610
|
]);
|
|
2525
2611
|
|
|
2526
2612
|
// src/ccda/identity.ts
|
|
@@ -2628,16 +2714,18 @@ function generateCcda(options = {}) {
|
|
|
2628
2714
|
const { seed = 0 } = options;
|
|
2629
2715
|
const documentType = resolveKind(CCDA_DOCUMENT_TYPES, options.documentType ?? "ccd");
|
|
2630
2716
|
const rng = createRng(seed);
|
|
2631
|
-
return
|
|
2717
|
+
return ccdaPeer().buildCcda(buildInit(rng, documentType));
|
|
2632
2718
|
}
|
|
2719
|
+
|
|
2720
|
+
// src/deid/loop.ts
|
|
2633
2721
|
var DEID_LOOP_POLICY_NAME = "synth-deid-loop-removal";
|
|
2634
2722
|
function deidLoopPolicy() {
|
|
2635
|
-
return
|
|
2723
|
+
return deidPeer().defineDeidPolicy({
|
|
2636
2724
|
name: DEID_LOOP_POLICY_NAME,
|
|
2637
2725
|
transforms: {
|
|
2638
|
-
[
|
|
2639
|
-
[
|
|
2640
|
-
[
|
|
2726
|
+
[deidPeer().SAFE_HARBOR_CATEGORIES.MRN]: "redact",
|
|
2727
|
+
[deidPeer().SAFE_HARBOR_CATEGORIES.HEALTH_PLAN_BENEFICIARY]: "redact",
|
|
2728
|
+
[deidPeer().SAFE_HARBOR_CATEGORIES.ACCOUNT]: "redact"
|
|
2641
2729
|
}
|
|
2642
2730
|
});
|
|
2643
2731
|
}
|
|
@@ -2774,7 +2862,8 @@ var DEID_LOOP_SKIPPED = Object.freeze([
|
|
|
2774
2862
|
reason: "@cosyte/synth does not generate DICOM, so there is nothing to pair."
|
|
2775
2863
|
})
|
|
2776
2864
|
]);
|
|
2777
|
-
var
|
|
2865
|
+
var policy;
|
|
2866
|
+
var loopPolicy = () => policy ??= deidLoopPolicy();
|
|
2778
2867
|
function residue(loci) {
|
|
2779
2868
|
return loci.map((l) => l.value).join("\n");
|
|
2780
2869
|
}
|
|
@@ -2799,8 +2888,8 @@ function hl7DeidLoop(options = {}) {
|
|
|
2799
2888
|
const kind = options.kind ?? "ORU^R01";
|
|
2800
2889
|
const message = generateHl7(kind, seed);
|
|
2801
2890
|
const original = message.toString();
|
|
2802
|
-
const planted = identifierSentinels(
|
|
2803
|
-
const deidDoc =
|
|
2891
|
+
const planted = identifierSentinels(deidHl7Peer().extractHl7Loci(message).loci, original);
|
|
2892
|
+
const deidDoc = deidHl7Peer().deidentifyHl7(message, { policy: loopPolicy() }).document;
|
|
2804
2893
|
const deidentified = deidDoc.toString();
|
|
2805
2894
|
return assembleVerdict({
|
|
2806
2895
|
format: "hl7",
|
|
@@ -2809,17 +2898,17 @@ function hl7DeidLoop(options = {}) {
|
|
|
2809
2898
|
planted,
|
|
2810
2899
|
original,
|
|
2811
2900
|
deidentified,
|
|
2812
|
-
phiResidue: residue(
|
|
2901
|
+
phiResidue: residue(deidHl7Peer().extractHl7Loci(deidDoc).loci),
|
|
2813
2902
|
clinicalCodes: HL7_CLINICAL
|
|
2814
2903
|
});
|
|
2815
2904
|
}
|
|
2816
2905
|
function fhirDeidLoop(options = {}) {
|
|
2817
2906
|
const seed = options.seed ?? 0;
|
|
2818
2907
|
const bundle = generateBundle({ seed });
|
|
2819
|
-
const original =
|
|
2820
|
-
const planted = identifierSentinels(
|
|
2821
|
-
const deidDoc =
|
|
2822
|
-
const deidentified =
|
|
2908
|
+
const original = fhirPeer().serializeResource(bundle);
|
|
2909
|
+
const planted = identifierSentinels(deidFhirPeer().extractFhirLoci(bundle).loci, original);
|
|
2910
|
+
const deidDoc = deidFhirPeer().deidentifyFhir(bundle, { policy: loopPolicy() }).document;
|
|
2911
|
+
const deidentified = fhirPeer().serializeResource(deidDoc);
|
|
2823
2912
|
return assembleVerdict({
|
|
2824
2913
|
format: "fhir",
|
|
2825
2914
|
artifact: "Bundle",
|
|
@@ -2827,7 +2916,7 @@ function fhirDeidLoop(options = {}) {
|
|
|
2827
2916
|
planted,
|
|
2828
2917
|
original,
|
|
2829
2918
|
deidentified,
|
|
2830
|
-
phiResidue: residue(
|
|
2919
|
+
phiResidue: residue(deidFhirPeer().extractFhirLoci(deidDoc).loci),
|
|
2831
2920
|
clinicalCodes: FHIR_CLINICAL
|
|
2832
2921
|
});
|
|
2833
2922
|
}
|
|
@@ -2849,9 +2938,9 @@ function x12DeidLoop(options = {}) {
|
|
|
2849
2938
|
const seed = options.seed ?? 0;
|
|
2850
2939
|
const variant = options.variant ?? "837P";
|
|
2851
2940
|
const interchange = generateX12(variant, seed);
|
|
2852
|
-
const original =
|
|
2853
|
-
const planted = identifierSentinels(
|
|
2854
|
-
const deidentified =
|
|
2941
|
+
const original = x12Peer().serializeX12(interchange);
|
|
2942
|
+
const planted = identifierSentinels(deidX12Peer().extractX12Loci(interchange).loci, original);
|
|
2943
|
+
const deidentified = deidX12Peer().deidentifyX12(interchange, { policy: loopPolicy() }).x12;
|
|
2855
2944
|
return assembleVerdict({
|
|
2856
2945
|
format: "x12",
|
|
2857
2946
|
artifact: variant,
|
|
@@ -2859,7 +2948,7 @@ function x12DeidLoop(options = {}) {
|
|
|
2859
2948
|
planted,
|
|
2860
2949
|
original,
|
|
2861
2950
|
deidentified,
|
|
2862
|
-
phiResidue: residue(
|
|
2951
|
+
phiResidue: residue(deidX12Peer().extractX12Loci(x12Peer().parseX12(deidentified)).loci),
|
|
2863
2952
|
clinicalCodes: X12_CLINICAL
|
|
2864
2953
|
});
|
|
2865
2954
|
}
|
|
@@ -2877,9 +2966,9 @@ function ncpdpTelecomDeidLoop(options = {}) {
|
|
|
2877
2966
|
const seed = options.seed ?? 0;
|
|
2878
2967
|
const transaction = options.transaction ?? "B1";
|
|
2879
2968
|
const original = generateTelecomWire(transaction, seed);
|
|
2880
|
-
const tx =
|
|
2881
|
-
const planted = identifierSentinels(
|
|
2882
|
-
const deidentified =
|
|
2969
|
+
const tx = ncpdpTelecomPeer().parseTelecom(original);
|
|
2970
|
+
const planted = identifierSentinels(deidNcpdpPeer().extractTelecomLoci(tx).loci, original);
|
|
2971
|
+
const deidentified = deidNcpdpPeer().deidentifyTelecom(tx, { policy: loopPolicy() }).telecom;
|
|
2883
2972
|
return assembleVerdict({
|
|
2884
2973
|
format: "ncpdp-telecom",
|
|
2885
2974
|
artifact: transaction,
|
|
@@ -2887,7 +2976,9 @@ function ncpdpTelecomDeidLoop(options = {}) {
|
|
|
2887
2976
|
planted,
|
|
2888
2977
|
original,
|
|
2889
2978
|
deidentified,
|
|
2890
|
-
phiResidue: residue(
|
|
2979
|
+
phiResidue: residue(
|
|
2980
|
+
deidNcpdpPeer().extractTelecomLoci(ncpdpTelecomPeer().parseTelecom(deidentified)).loci
|
|
2981
|
+
),
|
|
2891
2982
|
clinicalCodes: NCPDP_CLINICAL
|
|
2892
2983
|
});
|
|
2893
2984
|
}
|
|
@@ -2895,9 +2986,9 @@ function ccdaDeidLoop(options = {}) {
|
|
|
2895
2986
|
const seed = options.seed ?? 0;
|
|
2896
2987
|
const documentType = options.documentType ?? "ccd";
|
|
2897
2988
|
const doc = generateCcda({ seed, documentType: documentType === "ccd" ? "ccd" : "referralNote" });
|
|
2898
|
-
const original =
|
|
2989
|
+
const original = ccdaPeer().serializeCcda(doc);
|
|
2899
2990
|
const planted = recordTargetSentinels(original);
|
|
2900
|
-
const deidentified =
|
|
2991
|
+
const deidentified = deidCcdaPeer().deidentifyCcda(doc, { policy: loopPolicy() }).document.toString();
|
|
2901
2992
|
return assembleVerdict({
|
|
2902
2993
|
format: "ccda",
|
|
2903
2994
|
artifact: documentType === "ccd" ? "CCD" : "ReferralNote",
|
|
@@ -2912,9 +3003,9 @@ function ccdaDeidLoop(options = {}) {
|
|
|
2912
3003
|
function summarizeDeidCoverage(results) {
|
|
2913
3004
|
const byFormatMap = /* @__PURE__ */ new Map();
|
|
2914
3005
|
for (const r of results) {
|
|
2915
|
-
const
|
|
2916
|
-
|
|
2917
|
-
byFormatMap.set(r.format,
|
|
3006
|
+
const list = byFormatMap.get(r.format) ?? [];
|
|
3007
|
+
list.push(r);
|
|
3008
|
+
byFormatMap.set(r.format, list);
|
|
2918
3009
|
}
|
|
2919
3010
|
const byFormat = [];
|
|
2920
3011
|
for (const [format, runs] of byFormatMap) {
|