@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.
Files changed (46) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/astm/index.cjs +57 -19
  3. package/dist/astm/index.cjs.map +1 -1
  4. package/dist/astm/index.d.cts +7 -0
  5. package/dist/astm/index.d.ts +7 -0
  6. package/dist/astm/index.mjs +56 -19
  7. package/dist/astm/index.mjs.map +1 -1
  8. package/dist/ccda/index.cjs +76 -26
  9. package/dist/ccda/index.cjs.map +1 -1
  10. package/dist/ccda/index.d.cts +6 -0
  11. package/dist/ccda/index.d.ts +6 -0
  12. package/dist/ccda/index.mjs +63 -14
  13. package/dist/ccda/index.mjs.map +1 -1
  14. package/dist/deid/index.cjs +216 -125
  15. package/dist/deid/index.cjs.map +1 -1
  16. package/dist/deid/index.mjs +203 -113
  17. package/dist/deid/index.mjs.map +1 -1
  18. package/dist/fhir/index.cjs +146 -74
  19. package/dist/fhir/index.cjs.map +1 -1
  20. package/dist/fhir/index.d.cts +6 -0
  21. package/dist/fhir/index.d.ts +6 -0
  22. package/dist/fhir/index.mjs +145 -74
  23. package/dist/fhir/index.mjs.map +1 -1
  24. package/dist/hl7/index.cjs +53 -9
  25. package/dist/hl7/index.cjs.map +1 -1
  26. package/dist/hl7/index.d.cts +6 -0
  27. package/dist/hl7/index.d.ts +6 -0
  28. package/dist/hl7/index.mjs +52 -9
  29. package/dist/hl7/index.mjs.map +1 -1
  30. package/dist/index.cjs +1 -3
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.mjs +1 -3
  33. package/dist/index.mjs.map +1 -1
  34. package/dist/ncpdp/index.cjs +76 -23
  35. package/dist/ncpdp/index.cjs.map +1 -1
  36. package/dist/ncpdp/index.d.cts +7 -0
  37. package/dist/ncpdp/index.d.ts +7 -0
  38. package/dist/ncpdp/index.mjs +75 -23
  39. package/dist/ncpdp/index.mjs.map +1 -1
  40. package/dist/x12/index.cjs +72 -23
  41. package/dist/x12/index.cjs.map +1 -1
  42. package/dist/x12/index.d.cts +8 -1
  43. package/dist/x12/index.d.ts +8 -1
  44. package/dist/x12/index.mjs +71 -23
  45. package/dist/x12/index.mjs.map +1 -1
  46. package/package.json +20 -15
@@ -1,16 +1,12 @@
1
- import { extractHl7Loci, deidentifyHl7 } from '@cosyte/deid/hl7';
2
- import { extractFhirLoci, deidentifyFhir } from '@cosyte/deid/fhir';
3
- import { extractX12Loci, deidentifyX12 } from '@cosyte/deid/x12';
4
- import { extractTelecomLoci, deidentifyTelecom } from '@cosyte/deid/ncpdp';
5
- import { deidentifyCcda } from '@cosyte/deid/ccda';
6
- import { serializeResource, complex, list, primitive, decimal } from '@cosyte/fhir';
7
- import { serializeX12, parseX12, build835, build271, X12Decimal, build837D, build837I, build837P } from '@cosyte/x12';
8
- import { serializeCcda, buildCcda, NCI_ROUTE, SNOMED_CT, CVX, RXNORM, LOINC } from '@cosyte/ccda';
9
- import { parseTelecom, serializeTelecom, buildTelecomRequest } from '@cosyte/ncpdp/telecom';
10
- import { buildMessage } from '@cosyte/hl7';
11
- import { defineDeidPolicy, SAFE_HARBOR_CATEGORIES } from '@cosyte/deid';
1
+ import { createRequire } from 'module';
2
+ import { fileURLToPath } from 'url';
12
3
 
13
- // src/deid/index.ts
4
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
5
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
6
+ }) : x)(function(x) {
7
+ if (typeof require !== "undefined") return require.apply(this, arguments);
8
+ throw Error('Dynamic require of "' + x + '" is not supported');
9
+ });
14
10
 
15
11
  // src/rng/splitmix32.ts
16
12
  function splitmix32(seed) {
@@ -450,6 +446,40 @@ var safe = Object.freeze({
450
446
  npi,
451
447
  dea
452
448
  });
449
+ function defaultHost() {
450
+ if (typeof import.meta.resolve !== "function") return { require: __require, resolve: void 0 };
451
+ return { require: createRequire(import.meta.url), resolve: (s) => import.meta.resolve(s) };
452
+ }
453
+ function isRequireEsmRefusal(error) {
454
+ return error?.code === "ERR_REQUIRE_ESM";
455
+ }
456
+ function loadPeer(specifier, host) {
457
+ if (host.resolve === void 0) return host.require(specifier);
458
+ const entry = fileURLToPath(host.resolve(specifier));
459
+ try {
460
+ return host.require(entry);
461
+ } catch (error) {
462
+ if (!isRequireEsmRefusal(error)) throw error;
463
+ return host.require(specifier);
464
+ }
465
+ }
466
+ function lazyPeer(specifier, host) {
467
+ let loaded;
468
+ return () => loaded ??= loadPeer(specifier, defaultHost());
469
+ }
470
+
471
+ // src/peers.ts
472
+ var hl7Peer = lazyPeer("@cosyte/hl7");
473
+ var fhirPeer = lazyPeer("@cosyte/fhir");
474
+ var ccdaPeer = lazyPeer("@cosyte/ccda");
475
+ var x12Peer = lazyPeer("@cosyte/x12");
476
+ var ncpdpTelecomPeer = lazyPeer("@cosyte/ncpdp/telecom");
477
+ var deidPeer = lazyPeer("@cosyte/deid");
478
+ var deidHl7Peer = lazyPeer("@cosyte/deid/hl7");
479
+ var deidFhirPeer = lazyPeer("@cosyte/deid/fhir");
480
+ var deidX12Peer = lazyPeer("@cosyte/deid/x12");
481
+ var deidNcpdpPeer = lazyPeer("@cosyte/deid/ncpdp");
482
+ var deidCcdaPeer = lazyPeer("@cosyte/deid/ccda");
453
483
 
454
484
  // src/hl7/common.ts
455
485
  function seededTimestamp(rng) {
@@ -462,7 +492,7 @@ function seededTimestamp(rng) {
462
492
  function mshScaffold(rng, type) {
463
493
  const timestamp = seededTimestamp(rng);
464
494
  const controlId = `SYNTH${rng.digits(10)}`;
465
- const message = buildMessage({
495
+ const message = hl7Peer().buildMessage({
466
496
  type,
467
497
  sendingApp: "COSYTE-SYNTH",
468
498
  sendingFacility: "SYNTH-FAC",
@@ -913,36 +943,36 @@ function prop(name2, value) {
913
943
  return { name: name2, value };
914
944
  }
915
945
  function str(value) {
916
- return primitive(value);
946
+ return fhirPeer().primitive(value);
917
947
  }
918
948
  function dec(raw) {
919
- return primitive(decimal(raw));
949
+ return fhirPeer().primitive(fhirPeer().decimal(raw));
920
950
  }
921
951
  function bool(value) {
922
- return primitive(value);
952
+ return fhirPeer().primitive(value);
923
953
  }
924
954
  function coding(concept) {
925
- return complex([
955
+ return fhirPeer().complex([
926
956
  prop("system", str(concept.system)),
927
957
  prop("code", str(concept.code)),
928
958
  prop("display", str(concept.display))
929
959
  ]);
930
960
  }
931
961
  function codeableConcept(concept) {
932
- return complex([prop("coding", list([coding(concept)]))]);
962
+ return fhirPeer().complex([prop("coding", fhirPeer().list([coding(concept)]))]);
933
963
  }
934
964
  function reference(ref) {
935
- return complex([prop("reference", str(ref))]);
965
+ return fhirPeer().complex([prop("reference", str(ref))]);
936
966
  }
937
967
  function narrative(text) {
938
968
  const escaped = text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
939
- return complex([
969
+ return fhirPeer().complex([
940
970
  prop("status", str("generated")),
941
971
  prop("div", str(`<div xmlns="http://www.w3.org/1999/xhtml"><p>${escaped}</p></div>`))
942
972
  ]);
943
973
  }
944
974
  function meta(profiles) {
945
- return complex([prop("profile", list(profiles.map((p) => str(p))))]);
975
+ return fhirPeer().complex([prop("profile", fhirPeer().list(profiles.map((p) => str(p))))]);
946
976
  }
947
977
  function toFhirDate(ymd) {
948
978
  return `${ymd.slice(0, 4)}-${ymd.slice(4, 6)}-${ymd.slice(6, 8)}`;
@@ -959,13 +989,13 @@ function fhirPatientIdentity(rng) {
959
989
  return { id, person, mrn, birthDate, gender, address: address2, phone: phone2, email: email2 };
960
990
  }
961
991
  function mrnIdentifier(mrn) {
962
- return complex([
992
+ return fhirPeer().complex([
963
993
  prop(
964
994
  "type",
965
- complex([
995
+ fhirPeer().complex([
966
996
  prop(
967
997
  "coding",
968
- list([
998
+ fhirPeer().list([
969
999
  coding({
970
1000
  system: SYSTEM.IDENTIFIER_TYPE,
971
1001
  code: "MR",
@@ -1250,13 +1280,16 @@ var EXAMPLE_ENCOUNTER_CLASSES = Object.freeze([
1250
1280
  // src/fhir/patient.ts
1251
1281
  var PATIENT_PROFILES = Object.freeze(["base", "us-core"]);
1252
1282
  function ombExtension(url, category) {
1253
- return complex([
1283
+ return fhirPeer().complex([
1254
1284
  prop("url", str(url)),
1255
1285
  prop(
1256
1286
  "extension",
1257
- list([
1258
- complex([prop("url", str("ombCategory")), prop("valueCoding", coding(category))]),
1259
- complex([prop("url", str("text")), prop("valueString", str(category.display))])
1287
+ fhirPeer().list([
1288
+ fhirPeer().complex([
1289
+ prop("url", str("ombCategory")),
1290
+ prop("valueCoding", coding(category))
1291
+ ]),
1292
+ fhirPeer().complex([prop("url", str("text")), prop("valueString", str(category.display))])
1260
1293
  ])
1261
1294
  )
1262
1295
  ]);
@@ -1287,24 +1320,27 @@ function generatePatient(options = {}) {
1287
1320
  props.push(
1288
1321
  prop(
1289
1322
  "extension",
1290
- list([
1323
+ fhirPeer().list([
1291
1324
  ombExtension(US_CORE_RACE_EXTENSION, race),
1292
1325
  ombExtension(US_CORE_ETHNICITY_EXTENSION, ethnicity),
1293
- complex([prop("url", str(US_CORE_BIRTHSEX_EXTENSION)), prop("valueCode", str(birthsex))])
1326
+ fhirPeer().complex([
1327
+ prop("url", str(US_CORE_BIRTHSEX_EXTENSION)),
1328
+ prop("valueCode", str(birthsex))
1329
+ ])
1294
1330
  ])
1295
1331
  )
1296
1332
  );
1297
1333
  }
1298
- props.push(prop("identifier", list([mrnIdentifier(id.mrn)])));
1334
+ props.push(prop("identifier", fhirPeer().list([mrnIdentifier(id.mrn)])));
1299
1335
  props.push(prop("active", bool(true)));
1300
1336
  props.push(
1301
1337
  prop(
1302
1338
  "name",
1303
- list([
1304
- complex([
1339
+ fhirPeer().list([
1340
+ fhirPeer().complex([
1305
1341
  prop("use", str("official")),
1306
1342
  prop("family", str(id.person.family)),
1307
- prop("given", list([str(id.person.given)]))
1343
+ prop("given", fhirPeer().list([str(id.person.given)]))
1308
1344
  ])
1309
1345
  ])
1310
1346
  )
@@ -1312,13 +1348,13 @@ function generatePatient(options = {}) {
1312
1348
  props.push(
1313
1349
  prop(
1314
1350
  "telecom",
1315
- list([
1316
- complex([
1351
+ fhirPeer().list([
1352
+ fhirPeer().complex([
1317
1353
  prop("system", str("phone")),
1318
1354
  prop("value", str(id.phone)),
1319
1355
  prop("use", str("home"))
1320
1356
  ]),
1321
- complex([prop("system", str("email")), prop("value", str(id.email))])
1357
+ fhirPeer().complex([prop("system", str("email")), prop("value", str(id.email))])
1322
1358
  ])
1323
1359
  )
1324
1360
  );
@@ -1327,10 +1363,10 @@ function generatePatient(options = {}) {
1327
1363
  props.push(
1328
1364
  prop(
1329
1365
  "address",
1330
- list([
1331
- complex([
1366
+ fhirPeer().list([
1367
+ fhirPeer().complex([
1332
1368
  prop("use", str("home")),
1333
- prop("line", list([str(id.address.street)])),
1369
+ prop("line", fhirPeer().list([str(id.address.street)])),
1334
1370
  prop("city", str(id.address.city)),
1335
1371
  prop("state", str(id.address.state)),
1336
1372
  prop("postalCode", str(id.address.zip))
@@ -1338,8 +1374,10 @@ function generatePatient(options = {}) {
1338
1374
  ])
1339
1375
  )
1340
1376
  );
1341
- return complex(props);
1377
+ return fhirPeer().complex(props);
1342
1378
  }
1379
+
1380
+ // src/fhir/condition.ts
1343
1381
  function generateCondition(options = {}) {
1344
1382
  const { seed = 0, subject = "Patient/syn-patient-1", usCore = true } = options;
1345
1383
  const rng = createRng(seed);
@@ -1369,7 +1407,7 @@ function generateCondition(options = {}) {
1369
1407
  props.push(
1370
1408
  prop(
1371
1409
  "category",
1372
- list([
1410
+ fhirPeer().list([
1373
1411
  codeableConcept({
1374
1412
  system: SYSTEM.CONDITION_CATEGORY,
1375
1413
  code: "problem-list-item",
@@ -1380,15 +1418,17 @@ function generateCondition(options = {}) {
1380
1418
  );
1381
1419
  props.push(prop("code", codeableConcept(code)));
1382
1420
  props.push(prop("subject", reference(subject)));
1383
- return complex(props);
1421
+ return fhirPeer().complex(props);
1384
1422
  }
1423
+
1424
+ // src/fhir/observation.ts
1385
1425
  function drawValue(rng, concept) {
1386
1426
  const span = concept.high - concept.low;
1387
1427
  const raw = concept.low + rng.float() * span;
1388
1428
  return raw.toFixed(concept.decimals);
1389
1429
  }
1390
1430
  function valueQuantity(rng, concept) {
1391
- return complex([
1431
+ return fhirPeer().complex([
1392
1432
  prop("value", dec(drawValue(rng, concept))),
1393
1433
  prop("unit", str(concept.unit)),
1394
1434
  prop("system", str(SYSTEM.UCUM)),
@@ -1410,7 +1450,7 @@ function buildObservation(seed, subject, usCore, profileUrl, category, pool, eff
1410
1450
  props.push(
1411
1451
  prop(
1412
1452
  "category",
1413
- list([
1453
+ fhirPeer().list([
1414
1454
  codeableConcept({
1415
1455
  system: SYSTEM.OBSERVATION_CATEGORY,
1416
1456
  code: category.code,
@@ -1426,7 +1466,7 @@ function buildObservation(seed, subject, usCore, profileUrl, category, pool, eff
1426
1466
  const d = String(rng.int(1, 28)).padStart(2, "0");
1427
1467
  if (effective) props.push(prop("effectiveDateTime", str(`${String(y)}-${m}-${d}`)));
1428
1468
  props.push(prop("valueQuantity", valueQuantity(rng, concept)));
1429
- return complex(props);
1469
+ return fhirPeer().complex(props);
1430
1470
  }
1431
1471
  function generateObservationLab(options = {}) {
1432
1472
  const { seed = 0, subject = "Patient/syn-patient-1", usCore = true } = options;
@@ -1452,6 +1492,8 @@ function generateVitalSign(options = {}) {
1452
1492
  true
1453
1493
  );
1454
1494
  }
1495
+
1496
+ // src/fhir/medication-request.ts
1455
1497
  function generateMedicationRequest(options = {}) {
1456
1498
  const {
1457
1499
  seed = 0,
@@ -1476,8 +1518,10 @@ function generateMedicationRequest(options = {}) {
1476
1518
  props.push(prop("subject", reference(subject)));
1477
1519
  props.push(prop("authoredOn", str(`${String(y)}-${m}-${d}`)));
1478
1520
  props.push(prop("requester", reference(requester)));
1479
- return complex(props);
1521
+ return fhirPeer().complex(props);
1480
1522
  }
1523
+
1524
+ // src/fhir/encounter.ts
1481
1525
  function generateEncounter(options = {}) {
1482
1526
  const { seed = 0, subject = "Patient/syn-patient-1", usCore = true } = options;
1483
1527
  const rng = createRng(seed);
@@ -1494,8 +1538,8 @@ function generateEncounter(options = {}) {
1494
1538
  props.push(
1495
1539
  prop(
1496
1540
  "identifier",
1497
- list([
1498
- complex([
1541
+ fhirPeer().list([
1542
+ fhirPeer().complex([
1499
1543
  prop("system", str(`urn:oid:${id.assigningAuthorityOid}`)),
1500
1544
  prop("value", str(id.value))
1501
1545
  ])
@@ -1504,11 +1548,13 @@ function generateEncounter(options = {}) {
1504
1548
  );
1505
1549
  props.push(prop("status", str("finished")));
1506
1550
  props.push(prop("class", coding(cls)));
1507
- props.push(prop("type", list([codeableConcept(type)])));
1551
+ props.push(prop("type", fhirPeer().list([codeableConcept(type)])));
1508
1552
  props.push(prop("subject", reference(subject)));
1509
- props.push(prop("period", complex([prop("start", str(`${start}T09:00:00Z`))])));
1510
- return complex(props);
1553
+ props.push(prop("period", fhirPeer().complex([prop("start", str(`${start}T09:00:00Z`))])));
1554
+ return fhirPeer().complex(props);
1511
1555
  }
1556
+
1557
+ // src/fhir/immunization.ts
1512
1558
  function generateImmunization(options = {}) {
1513
1559
  const { seed = 0, patient = "Patient/syn-patient-1", usCore = true } = options;
1514
1560
  const rng = createRng(seed);
@@ -1525,8 +1571,10 @@ function generateImmunization(options = {}) {
1525
1571
  props.push(prop("patient", reference(patient)));
1526
1572
  props.push(prop("occurrenceDateTime", str(occurrence)));
1527
1573
  props.push(prop("primarySource", bool(true)));
1528
- return complex(props);
1574
+ return fhirPeer().complex(props);
1529
1575
  }
1576
+
1577
+ // src/fhir/allergy-intolerance.ts
1530
1578
  function generateAllergyIntolerance(options = {}) {
1531
1579
  const { seed = 0, patient = "Patient/syn-patient-1", usCore = true } = options;
1532
1580
  const rng = createRng(seed);
@@ -1559,11 +1607,17 @@ function generateAllergyIntolerance(options = {}) {
1559
1607
  props.push(
1560
1608
  prop(
1561
1609
  "reaction",
1562
- list([complex([prop("manifestation", list([codeableConcept(manifestation)]))])])
1610
+ fhirPeer().list([
1611
+ fhirPeer().complex([
1612
+ prop("manifestation", fhirPeer().list([codeableConcept(manifestation)]))
1613
+ ])
1614
+ ])
1563
1615
  )
1564
1616
  );
1565
- return complex(props);
1617
+ return fhirPeer().complex(props);
1566
1618
  }
1619
+
1620
+ // src/fhir/procedure.ts
1567
1621
  function generateProcedure(options = {}) {
1568
1622
  const { seed = 0, subject = "Patient/syn-patient-1", usCore = true } = options;
1569
1623
  const rng = createRng(seed);
@@ -1579,8 +1633,10 @@ function generateProcedure(options = {}) {
1579
1633
  props.push(prop("code", codeableConcept(code)));
1580
1634
  props.push(prop("subject", reference(subject)));
1581
1635
  props.push(prop("performedDateTime", str(`${performed}T10:00:00Z`)));
1582
- return complex(props);
1636
+ return fhirPeer().complex(props);
1583
1637
  }
1638
+
1639
+ // src/fhir/diagnostic-report.ts
1584
1640
  function generateDiagnosticReport(options = {}) {
1585
1641
  const { seed = 0, subject = "Patient/syn-patient-1", results = [], usCore = true } = options;
1586
1642
  const rng = createRng(seed);
@@ -1596,7 +1652,7 @@ function generateDiagnosticReport(options = {}) {
1596
1652
  props.push(
1597
1653
  prop(
1598
1654
  "category",
1599
- list([
1655
+ fhirPeer().list([
1600
1656
  codeableConcept({
1601
1657
  system: SYSTEM.DIAGNOSTIC_SERVICE_SECTION,
1602
1658
  code: "LAB",
@@ -1610,15 +1666,17 @@ function generateDiagnosticReport(options = {}) {
1610
1666
  props.push(prop("effectiveDateTime", str(`${day}T08:30:00Z`)));
1611
1667
  props.push(prop("issued", str(`${day}T09:00:00.000Z`)));
1612
1668
  if (results.length > 0) {
1613
- props.push(prop("result", list(results.map((r) => reference(r)))));
1669
+ props.push(prop("result", fhirPeer().list(results.map((r) => reference(r)))));
1614
1670
  }
1615
- return complex(props);
1671
+ return fhirPeer().complex(props);
1616
1672
  }
1673
+
1674
+ // src/fhir/composition.ts
1617
1675
  function section(sec) {
1618
- return complex([
1676
+ return fhirPeer().complex([
1619
1677
  prop("title", str(sec.title)),
1620
1678
  prop("code", codeableConcept({ system: SYSTEM.LOINC, code: sec.code, display: sec.title })),
1621
- prop("entry", list(sec.entries.map((e) => reference(e))))
1679
+ prop("entry", fhirPeer().list(sec.entries.map((e) => reference(e))))
1622
1680
  ]);
1623
1681
  }
1624
1682
  function buildComposition(rng, input) {
@@ -1637,12 +1695,12 @@ function buildComposition(rng, input) {
1637
1695
  ),
1638
1696
  prop("subject", reference(input.subject)),
1639
1697
  prop("date", str(`${input.date}T09:00:00Z`)),
1640
- prop("author", list([reference(input.organization)])),
1698
+ prop("author", fhirPeer().list([reference(input.organization)])),
1641
1699
  prop("title", str("Synthetic Continuity of Care Document")),
1642
1700
  prop("custodian", reference(input.organization)),
1643
- prop("section", list(input.sections.map((s) => section(s))))
1701
+ prop("section", fhirPeer().list(input.sections.map((s) => section(s))))
1644
1702
  ];
1645
- return complex(props);
1703
+ return fhirPeer().complex(props);
1646
1704
  }
1647
1705
 
1648
1706
  // src/fhir/bundle.ts
@@ -1657,14 +1715,14 @@ function resourceTypeOf(resource) {
1657
1715
  }
1658
1716
  function buildOrganization(rng) {
1659
1717
  const id = safe.identifier(rng, "AN");
1660
- return complex([
1718
+ return fhirPeer().complex([
1661
1719
  prop("resourceType", str("Organization")),
1662
1720
  prop("id", str(`syn-org-${rng.digits(8)}`)),
1663
1721
  prop("text", narrative("Synthetic health organization.")),
1664
1722
  prop(
1665
1723
  "identifier",
1666
- list([
1667
- complex([
1724
+ fhirPeer().list([
1725
+ fhirPeer().complex([
1668
1726
  prop("system", str(`urn:oid:${id.assigningAuthorityOid}`)),
1669
1727
  prop("value", str(id.value))
1670
1728
  ])
@@ -1777,11 +1835,14 @@ function generateBundle(options = {}) {
1777
1835
  entryProps.push(
1778
1836
  prop(
1779
1837
  "request",
1780
- complex([prop("method", str("POST")), prop("url", str(resourceTypeOf(member.resource)))])
1838
+ fhirPeer().complex([
1839
+ prop("method", str("POST")),
1840
+ prop("url", str(resourceTypeOf(member.resource)))
1841
+ ])
1781
1842
  )
1782
1843
  );
1783
1844
  }
1784
- return complex(entryProps);
1845
+ return fhirPeer().complex(entryProps);
1785
1846
  });
1786
1847
  const props = [
1787
1848
  prop("resourceType", str("Bundle")),
@@ -1792,7 +1853,7 @@ function generateBundle(options = {}) {
1792
1853
  props.push(
1793
1854
  prop(
1794
1855
  "identifier",
1795
- complex([
1856
+ fhirPeer().complex([
1796
1857
  prop("system", str(`urn:oid:${id.assigningAuthorityOid}`)),
1797
1858
  prop("value", str(`urn:uuid:${safe.uuid(rng)}`))
1798
1859
  ])
@@ -1801,11 +1862,13 @@ function generateBundle(options = {}) {
1801
1862
  }
1802
1863
  props.push(prop("type", str(type)));
1803
1864
  if (type === "document") props.push(prop("timestamp", str(`${spine.date}T09:00:00.000Z`)));
1804
- props.push(prop("entry", list(entries)));
1805
- return complex(props);
1865
+ props.push(prop("entry", fhirPeer().list(entries)));
1866
+ return fhirPeer().complex(props);
1806
1867
  }
1868
+
1869
+ // src/x12/money.ts
1807
1870
  function dec2(value) {
1808
- const d = X12Decimal.fromString(value);
1871
+ const d = x12Peer().X12Decimal.fromString(value);
1809
1872
  if (d === void 0) throw new SynthError(SYNTH_FATAL_CODES.SYNTH_INVALID_DECIMAL);
1810
1873
  return d;
1811
1874
  }
@@ -1888,12 +1951,12 @@ var PROCEDURE_MODIFIERS = Object.freeze(["25", "59", "76", "GT"]);
1888
1951
  var PLACES_OF_SERVICE = Object.freeze(["11", "22", "21", "12", "49"]);
1889
1952
  var DIAGNOSES = Object.freeze(
1890
1953
  [
1891
- { code: "J20.9", label: "acute bronchitis, unspecified" },
1892
- { code: "E11.9", label: "type 2 diabetes mellitus without complications" },
1954
+ { code: "J209", label: "acute bronchitis, unspecified" },
1955
+ { code: "E119", label: "type 2 diabetes mellitus without complications" },
1893
1956
  { code: "I10", label: "essential (primary) hypertension" },
1894
- { code: "M54.5", label: "low back pain" },
1895
- { code: "R07.9", label: "chest pain, unspecified" },
1896
- { code: "Z00.00", label: "general adult medical exam without abnormal findings" }
1957
+ { code: "M545", label: "low back pain" },
1958
+ { code: "R079", label: "chest pain, unspecified" },
1959
+ { code: "Z0000", label: "general adult medical exam without abnormal findings" }
1897
1960
  ].map((entry) => Object.freeze(entry))
1898
1961
  );
1899
1962
  var REVENUE_CODES = Object.freeze(
@@ -2110,11 +2173,11 @@ function generate837(variant, options) {
2110
2173
  const spec = specOf(rng, resolved);
2111
2174
  switch (resolved) {
2112
2175
  case "P":
2113
- return build837P(spec);
2176
+ return x12Peer().build837P(spec);
2114
2177
  case "I":
2115
- return build837I(spec);
2178
+ return x12Peer().build837I(spec);
2116
2179
  case "D":
2117
- return build837D(spec);
2180
+ return x12Peer().build837D(spec);
2118
2181
  }
2119
2182
  }
2120
2183
  function generate837P(options) {
@@ -2126,6 +2189,8 @@ function generate837I(options) {
2126
2189
  function generate837D(options) {
2127
2190
  return generate837("D", options);
2128
2191
  }
2192
+
2193
+ // src/x12/remit-835.ts
2129
2194
  function generate835(options) {
2130
2195
  const rng = createRng(options.seed);
2131
2196
  const partners = x12TradingPartners(rng);
@@ -2226,8 +2291,10 @@ function generate835(options) {
2226
2291
  },
2227
2292
  claims: [claim]
2228
2293
  };
2229
- return build835(spec);
2294
+ return x12Peer().build835(spec);
2230
2295
  }
2296
+
2297
+ // src/x12/eligibility-271.ts
2231
2298
  function generate271(options) {
2232
2299
  const rng = createRng(options.seed);
2233
2300
  const partners = x12TradingPartners(rng);
@@ -2297,7 +2364,8 @@ function generate271(options) {
2297
2364
  serviceTypeCodes: serviceTypes,
2298
2365
  inPlanNetwork: "Y",
2299
2366
  monetaryAmount: dec2(money(rng.int(500, 5e3))),
2300
- percent: dec2(String(rng.pick([80, 90, 100])))
2367
+ percent: dec2(rng.pick([".8", ".9", "1"]))
2368
+ // EB-08 is a decimal fraction
2301
2369
  }
2302
2370
  ]
2303
2371
  }
@@ -2307,7 +2375,7 @@ function generate271(options) {
2307
2375
  }
2308
2376
  ]
2309
2377
  };
2310
- return build271(spec);
2378
+ return x12Peer().build271(spec);
2311
2379
  }
2312
2380
 
2313
2381
  // src/ncpdp/identity.ts
@@ -2363,6 +2431,8 @@ var EXAMPLE_DRUGS = Object.freeze(
2363
2431
  ].map((entry) => Object.freeze(entry))
2364
2432
  );
2365
2433
  var DAW_CODES = Object.freeze(["0", "1", "2"]);
2434
+
2435
+ // src/ncpdp/telecom.ts
2366
2436
  var SYNTHETIC_BIN = "999999";
2367
2437
  function digitsOnly(value) {
2368
2438
  return value.replace(/\D/g, "");
@@ -2446,7 +2516,8 @@ function claimSegment(rng, minimal) {
2446
2516
  field("E1", "03"),
2447
2517
  // 03 = NDC
2448
2518
  field("D7", drug.ndc),
2449
- field("E7", String(rng.int(30, 90))),
2519
+ field("E7", String(rng.int(30, 90) * 1e3)),
2520
+ // 442-E7 carries three implied decimals
2450
2521
  field("D5", String(rng.pick([30, 60, 90]))),
2451
2522
  field("D8", rng.pick(DAW_CODES))
2452
2523
  ]
@@ -2462,7 +2533,9 @@ function generateTelecom(code, options) {
2462
2533
  prescriberSegment(rng),
2463
2534
  claimSegment(rng, false)
2464
2535
  ];
2465
- return serializeTelecom(buildTelecomRequest({ header: head, segments }));
2536
+ return ncpdpTelecomPeer().serializeTelecom(
2537
+ ncpdpTelecomPeer().buildTelecomRequest({ header: head, segments })
2538
+ );
2466
2539
  }
2467
2540
  function generateB1(options) {
2468
2541
  return generateTelecom("B1", options);
@@ -2473,6 +2546,18 @@ function generateB2(options) {
2473
2546
  function generateB3(options) {
2474
2547
  return generateTelecom("B3", options);
2475
2548
  }
2549
+
2550
+ // src/ccda/example-codes.ts
2551
+ var LOINC_OID = "2.16.840.1.113883.6.1";
2552
+ var SNOMED_CT_OID = "2.16.840.1.113883.6.96";
2553
+ var RXNORM_OID = "2.16.840.1.113883.6.88";
2554
+ var CVX_OID = "2.16.840.1.113883.12.292";
2555
+ var NCI_ROUTE_OID = "2.16.840.1.113883.3.26.1.1";
2556
+ var LOINC = LOINC_OID;
2557
+ var SNOMED_CT = SNOMED_CT_OID;
2558
+ var RXNORM = RXNORM_OID;
2559
+ var CVX = CVX_OID;
2560
+ var NCI_ROUTE = NCI_ROUTE_OID;
2476
2561
  var URI_TO_OID = Object.freeze({
2477
2562
  "http://loinc.org": LOINC,
2478
2563
  "http://snomed.info/sct": SNOMED_CT,
@@ -2626,16 +2711,18 @@ function generateCcda(options = {}) {
2626
2711
  const { seed = 0 } = options;
2627
2712
  const documentType = resolveKind(CCDA_DOCUMENT_TYPES, options.documentType ?? "ccd");
2628
2713
  const rng = createRng(seed);
2629
- return buildCcda(buildInit(rng, documentType));
2714
+ return ccdaPeer().buildCcda(buildInit(rng, documentType));
2630
2715
  }
2716
+
2717
+ // src/deid/loop.ts
2631
2718
  var DEID_LOOP_POLICY_NAME = "synth-deid-loop-removal";
2632
2719
  function deidLoopPolicy() {
2633
- return defineDeidPolicy({
2720
+ return deidPeer().defineDeidPolicy({
2634
2721
  name: DEID_LOOP_POLICY_NAME,
2635
2722
  transforms: {
2636
- [SAFE_HARBOR_CATEGORIES.MRN]: "redact",
2637
- [SAFE_HARBOR_CATEGORIES.HEALTH_PLAN_BENEFICIARY]: "redact",
2638
- [SAFE_HARBOR_CATEGORIES.ACCOUNT]: "redact"
2723
+ [deidPeer().SAFE_HARBOR_CATEGORIES.MRN]: "redact",
2724
+ [deidPeer().SAFE_HARBOR_CATEGORIES.HEALTH_PLAN_BENEFICIARY]: "redact",
2725
+ [deidPeer().SAFE_HARBOR_CATEGORIES.ACCOUNT]: "redact"
2639
2726
  }
2640
2727
  });
2641
2728
  }
@@ -2772,7 +2859,8 @@ var DEID_LOOP_SKIPPED = Object.freeze([
2772
2859
  reason: "@cosyte/synth does not generate DICOM, so there is nothing to pair."
2773
2860
  })
2774
2861
  ]);
2775
- var POLICY = deidLoopPolicy();
2862
+ var policy;
2863
+ var loopPolicy = () => policy ??= deidLoopPolicy();
2776
2864
  function residue(loci) {
2777
2865
  return loci.map((l) => l.value).join("\n");
2778
2866
  }
@@ -2797,8 +2885,8 @@ function hl7DeidLoop(options = {}) {
2797
2885
  const kind = options.kind ?? "ORU^R01";
2798
2886
  const message = generateHl7(kind, seed);
2799
2887
  const original = message.toString();
2800
- const planted = identifierSentinels(extractHl7Loci(message).loci, original);
2801
- const deidDoc = deidentifyHl7(message, { policy: POLICY }).document;
2888
+ const planted = identifierSentinels(deidHl7Peer().extractHl7Loci(message).loci, original);
2889
+ const deidDoc = deidHl7Peer().deidentifyHl7(message, { policy: loopPolicy() }).document;
2802
2890
  const deidentified = deidDoc.toString();
2803
2891
  return assembleVerdict({
2804
2892
  format: "hl7",
@@ -2807,17 +2895,17 @@ function hl7DeidLoop(options = {}) {
2807
2895
  planted,
2808
2896
  original,
2809
2897
  deidentified,
2810
- phiResidue: residue(extractHl7Loci(deidDoc).loci),
2898
+ phiResidue: residue(deidHl7Peer().extractHl7Loci(deidDoc).loci),
2811
2899
  clinicalCodes: HL7_CLINICAL
2812
2900
  });
2813
2901
  }
2814
2902
  function fhirDeidLoop(options = {}) {
2815
2903
  const seed = options.seed ?? 0;
2816
2904
  const bundle = generateBundle({ seed });
2817
- const original = serializeResource(bundle);
2818
- const planted = identifierSentinels(extractFhirLoci(bundle).loci, original);
2819
- const deidDoc = deidentifyFhir(bundle, { policy: POLICY }).document;
2820
- const deidentified = serializeResource(deidDoc);
2905
+ const original = fhirPeer().serializeResource(bundle);
2906
+ const planted = identifierSentinels(deidFhirPeer().extractFhirLoci(bundle).loci, original);
2907
+ const deidDoc = deidFhirPeer().deidentifyFhir(bundle, { policy: loopPolicy() }).document;
2908
+ const deidentified = fhirPeer().serializeResource(deidDoc);
2821
2909
  return assembleVerdict({
2822
2910
  format: "fhir",
2823
2911
  artifact: "Bundle",
@@ -2825,7 +2913,7 @@ function fhirDeidLoop(options = {}) {
2825
2913
  planted,
2826
2914
  original,
2827
2915
  deidentified,
2828
- phiResidue: residue(extractFhirLoci(deidDoc).loci),
2916
+ phiResidue: residue(deidFhirPeer().extractFhirLoci(deidDoc).loci),
2829
2917
  clinicalCodes: FHIR_CLINICAL
2830
2918
  });
2831
2919
  }
@@ -2847,9 +2935,9 @@ function x12DeidLoop(options = {}) {
2847
2935
  const seed = options.seed ?? 0;
2848
2936
  const variant = options.variant ?? "837P";
2849
2937
  const interchange = generateX12(variant, seed);
2850
- const original = serializeX12(interchange);
2851
- const planted = identifierSentinels(extractX12Loci(interchange).loci, original);
2852
- const deidentified = deidentifyX12(interchange, { policy: POLICY }).x12;
2938
+ const original = x12Peer().serializeX12(interchange);
2939
+ const planted = identifierSentinels(deidX12Peer().extractX12Loci(interchange).loci, original);
2940
+ const deidentified = deidX12Peer().deidentifyX12(interchange, { policy: loopPolicy() }).x12;
2853
2941
  return assembleVerdict({
2854
2942
  format: "x12",
2855
2943
  artifact: variant,
@@ -2857,7 +2945,7 @@ function x12DeidLoop(options = {}) {
2857
2945
  planted,
2858
2946
  original,
2859
2947
  deidentified,
2860
- phiResidue: residue(extractX12Loci(parseX12(deidentified)).loci),
2948
+ phiResidue: residue(deidX12Peer().extractX12Loci(x12Peer().parseX12(deidentified)).loci),
2861
2949
  clinicalCodes: X12_CLINICAL
2862
2950
  });
2863
2951
  }
@@ -2875,9 +2963,9 @@ function ncpdpTelecomDeidLoop(options = {}) {
2875
2963
  const seed = options.seed ?? 0;
2876
2964
  const transaction = options.transaction ?? "B1";
2877
2965
  const original = generateTelecomWire(transaction, seed);
2878
- const tx = parseTelecom(original);
2879
- const planted = identifierSentinels(extractTelecomLoci(tx).loci, original);
2880
- const deidentified = deidentifyTelecom(tx, { policy: POLICY }).telecom;
2966
+ const tx = ncpdpTelecomPeer().parseTelecom(original);
2967
+ const planted = identifierSentinels(deidNcpdpPeer().extractTelecomLoci(tx).loci, original);
2968
+ const deidentified = deidNcpdpPeer().deidentifyTelecom(tx, { policy: loopPolicy() }).telecom;
2881
2969
  return assembleVerdict({
2882
2970
  format: "ncpdp-telecom",
2883
2971
  artifact: transaction,
@@ -2885,7 +2973,9 @@ function ncpdpTelecomDeidLoop(options = {}) {
2885
2973
  planted,
2886
2974
  original,
2887
2975
  deidentified,
2888
- phiResidue: residue(extractTelecomLoci(parseTelecom(deidentified)).loci),
2976
+ phiResidue: residue(
2977
+ deidNcpdpPeer().extractTelecomLoci(ncpdpTelecomPeer().parseTelecom(deidentified)).loci
2978
+ ),
2889
2979
  clinicalCodes: NCPDP_CLINICAL
2890
2980
  });
2891
2981
  }
@@ -2893,9 +2983,9 @@ function ccdaDeidLoop(options = {}) {
2893
2983
  const seed = options.seed ?? 0;
2894
2984
  const documentType = options.documentType ?? "ccd";
2895
2985
  const doc = generateCcda({ seed, documentType: documentType === "ccd" ? "ccd" : "referralNote" });
2896
- const original = serializeCcda(doc);
2986
+ const original = ccdaPeer().serializeCcda(doc);
2897
2987
  const planted = recordTargetSentinels(original);
2898
- const deidentified = deidentifyCcda(doc, { policy: POLICY }).document.toString();
2988
+ const deidentified = deidCcdaPeer().deidentifyCcda(doc, { policy: loopPolicy() }).document.toString();
2899
2989
  return assembleVerdict({
2900
2990
  format: "ccda",
2901
2991
  artifact: documentType === "ccd" ? "CCD" : "ReferralNote",
@@ -2910,9 +3000,9 @@ function ccdaDeidLoop(options = {}) {
2910
3000
  function summarizeDeidCoverage(results) {
2911
3001
  const byFormatMap = /* @__PURE__ */ new Map();
2912
3002
  for (const r of results) {
2913
- const list10 = byFormatMap.get(r.format) ?? [];
2914
- list10.push(r);
2915
- byFormatMap.set(r.format, list10);
3003
+ const list = byFormatMap.get(r.format) ?? [];
3004
+ list.push(r);
3005
+ byFormatMap.set(r.format, list);
2916
3006
  }
2917
3007
  const byFormat = [];
2918
3008
  for (const [format, runs] of byFormatMap) {