@cosyte/synth 0.1.8 → 0.1.10
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 +37 -0
- package/README.md +28 -17
- package/dist/animal-code-Bdl_9Jma.d.cts +30 -0
- package/dist/animal-code-Bdl_9Jma.d.ts +30 -0
- package/dist/astm/index.cjs +150 -15
- package/dist/astm/index.cjs.map +1 -1
- package/dist/astm/index.d.cts +22 -9
- package/dist/astm/index.d.ts +22 -9
- package/dist/astm/index.mjs +150 -15
- package/dist/astm/index.mjs.map +1 -1
- package/dist/ccda/index.cjs +150 -15
- package/dist/ccda/index.cjs.map +1 -1
- package/dist/ccda/index.d.cts +12 -3
- package/dist/ccda/index.d.ts +12 -3
- package/dist/ccda/index.mjs +150 -15
- package/dist/ccda/index.mjs.map +1 -1
- package/dist/deid/index.cjs +540 -28
- package/dist/deid/index.cjs.map +1 -1
- package/dist/deid/index.d.cts +2 -1
- package/dist/deid/index.d.ts +2 -1
- package/dist/deid/index.mjs +540 -28
- package/dist/deid/index.mjs.map +1 -1
- package/dist/fhir/index.cjs +145 -12
- package/dist/fhir/index.cjs.map +1 -1
- package/dist/fhir/index.d.cts +4 -1
- package/dist/fhir/index.d.ts +4 -1
- package/dist/fhir/index.mjs +145 -12
- package/dist/fhir/index.mjs.map +1 -1
- package/dist/hl7/index.cjs +569 -37
- package/dist/hl7/index.cjs.map +1 -1
- package/dist/hl7/index.d.cts +402 -111
- package/dist/hl7/index.d.ts +402 -111
- package/dist/hl7/index.mjs +560 -38
- package/dist/hl7/index.mjs.map +1 -1
- package/dist/index.cjs +124 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +183 -10
- package/dist/index.d.ts +183 -10
- package/dist/index.mjs +115 -14
- package/dist/index.mjs.map +1 -1
- package/dist/ncpdp/index.cjs +145 -12
- package/dist/ncpdp/index.cjs.map +1 -1
- package/dist/ncpdp/index.d.cts +4 -1
- package/dist/ncpdp/index.d.ts +4 -1
- package/dist/ncpdp/index.mjs +145 -12
- package/dist/ncpdp/index.mjs.map +1 -1
- package/dist/{quirk-BfObsiWV.d.ts → quirk-CzknuYUo.d.ts} +16 -5
- package/dist/{quirk-BCSs1jPt.d.cts → quirk-Q5AxzHSC.d.cts} +16 -5
- package/dist/x12/index.cjs +145 -12
- package/dist/x12/index.cjs.map +1 -1
- package/dist/x12/index.d.cts +4 -1
- package/dist/x12/index.d.ts +4 -1
- package/dist/x12/index.mjs +145 -12
- package/dist/x12/index.mjs.map +1 -1
- package/package.json +17 -6
package/dist/hl7/index.cjs
CHANGED
|
@@ -73,7 +73,11 @@ var SYNTH_FATAL_CODES = Object.freeze({
|
|
|
73
73
|
SYNTH_INVALID_DECIMAL: "SYNTH_INVALID_DECIMAL",
|
|
74
74
|
/** An integer range was requested with its maximum below its minimum. Fatal. */
|
|
75
75
|
SYNTH_INVALID_RANGE: "SYNTH_INVALID_RANGE",
|
|
76
|
-
/**
|
|
76
|
+
/**
|
|
77
|
+
* A value was drawn from an empty pool. Fatal, never a fabricated substitute. A corpus given an
|
|
78
|
+
* empty `mix`, `triggers` or `quirks` list (or a profile whose `quirks` is an empty list) raises it
|
|
79
|
+
* too: there is no kind to cycle through, and an empty list is never read as the default.
|
|
80
|
+
*/
|
|
77
81
|
SYNTH_EMPTY_POOL: "SYNTH_EMPTY_POOL",
|
|
78
82
|
/** A `defineSynthProfile` spec was not usable (a missing or blank `name`). Fatal. */
|
|
79
83
|
SYNTH_INVALID_PROFILE: "SYNTH_INVALID_PROFILE",
|
|
@@ -92,7 +96,21 @@ var SYNTH_FATAL_CODES = Object.freeze({
|
|
|
92
96
|
* apart without matching message text. Fatal, and raised **before** anything is generated: a
|
|
93
97
|
* mislabelled artifact is worse than no artifact.
|
|
94
98
|
*/
|
|
95
|
-
SYNTH_PROFILE_NOT_GENERATED: "SYNTH_PROFILE_NOT_GENERATED"
|
|
99
|
+
SYNTH_PROFILE_NOT_GENERATED: "SYNTH_PROFILE_NOT_GENERATED",
|
|
100
|
+
/**
|
|
101
|
+
* The sibling parser a generator builds through is not installed. Raised on the first call that
|
|
102
|
+
* needs it, by both builds, only when the missing package is the parser itself: a missing
|
|
103
|
+
* dependency of an installed parser is thrown as Node.js raised it. The error carries the parser's
|
|
104
|
+
* package name on `peer`, a message from {@link SYNTH_PEER_MESSAGES} that names its install
|
|
105
|
+
* command, and the error Node.js raised on `cause`.
|
|
106
|
+
*/
|
|
107
|
+
SYNTH_PEER_NOT_INSTALLED: "SYNTH_PEER_NOT_INSTALLED",
|
|
108
|
+
/**
|
|
109
|
+
* An HL7 v2 `ACK` was asked for an inbound message that carries no MSH-10 message control id.
|
|
110
|
+
* MSA-2 must echo that id, and an acknowledgment that cannot be matched to the message it answers
|
|
111
|
+
* is not a fixture worth having, so nothing is generated.
|
|
112
|
+
*/
|
|
113
|
+
SYNTH_ACK_UNCORRELATED: "SYNTH_ACK_UNCORRELATED"
|
|
96
114
|
});
|
|
97
115
|
var SYNTH_FATAL_MESSAGES = Object.freeze({
|
|
98
116
|
SYNTH_UNSUPPORTED_FORMAT: "The requested format is not generable by this build. A generator has no byte fallback: it builds through a parser's own serializer or it refuses.",
|
|
@@ -105,18 +123,38 @@ var SYNTH_FATAL_MESSAGES = Object.freeze({
|
|
|
105
123
|
SYNTH_EMPTY_POOL: "A value was drawn from an empty pool.",
|
|
106
124
|
SYNTH_INVALID_PROFILE: "defineSynthProfile requires a non-empty string name.",
|
|
107
125
|
SYNTH_UNSUPPORTED_KIND: "The requested kind, document type, corpus mix entry, variant or profile is not one this generator supports. The supported set is the exported union for that option.",
|
|
108
|
-
SYNTH_PROFILE_NOT_GENERATED: "The requested profile is published by the adopted implementation guide, and this build does not generate it. The coverage surface reports, per adopted profile, whether it is generated."
|
|
126
|
+
SYNTH_PROFILE_NOT_GENERATED: "The requested profile is published by the adopted implementation guide, and this build does not generate it. The coverage surface reports, per adopted profile, whether it is generated.",
|
|
127
|
+
SYNTH_PEER_NOT_INSTALLED: "A sibling @cosyte parser this generator builds through is not installed. Install it beside @cosyte/synth.",
|
|
128
|
+
SYNTH_ACK_UNCORRELATED: (
|
|
129
|
+
// Stryker disable next-line all: a module-level table runs once, at import; the docs test holds it.
|
|
130
|
+
"The inbound message has no MSH-10 control id for an ACK to echo in MSA-2."
|
|
131
|
+
)
|
|
132
|
+
});
|
|
133
|
+
var SYNTH_PEER_MESSAGES = Object.freeze({
|
|
134
|
+
"@cosyte/hl7": "@cosyte/hl7 is not installed, and this generator builds through it. Install it beside @cosyte/synth: npm install @cosyte/hl7",
|
|
135
|
+
"@cosyte/fhir": "@cosyte/fhir is not installed, and this generator builds through it. Install it beside @cosyte/synth: npm install @cosyte/fhir",
|
|
136
|
+
"@cosyte/ccda": "@cosyte/ccda is not installed, and this generator builds through it. Install it beside @cosyte/synth: npm install @cosyte/ccda",
|
|
137
|
+
"@cosyte/x12": "@cosyte/x12 is not installed, and this generator builds through it. Install it beside @cosyte/synth: npm install @cosyte/x12",
|
|
138
|
+
"@cosyte/ncpdp": "@cosyte/ncpdp is not installed, and this generator builds through it. Install it beside @cosyte/synth: npm install @cosyte/ncpdp",
|
|
139
|
+
"@cosyte/astm": "@cosyte/astm is not installed, and this generator builds through it. Install it beside @cosyte/synth: npm install @cosyte/astm",
|
|
140
|
+
"@cosyte/deid": "@cosyte/deid is not installed, and this generator builds through it. Install it beside @cosyte/synth: npm install @cosyte/deid"
|
|
109
141
|
});
|
|
110
142
|
var SynthError = class extends Error {
|
|
111
143
|
/** The stable fatal code. */
|
|
112
144
|
code;
|
|
113
145
|
/**
|
|
114
146
|
* @param code - The stable {@link SynthFatalCode}. The message comes from the frozen registry.
|
|
147
|
+
* @param options - The error that caused this one, and for a missing parser its package.
|
|
115
148
|
*/
|
|
116
|
-
constructor(code) {
|
|
117
|
-
|
|
149
|
+
constructor(code, options = {}) {
|
|
150
|
+
const peer = code === SYNTH_FATAL_CODES.SYNTH_PEER_NOT_INSTALLED ? options.peer : void 0;
|
|
151
|
+
super(
|
|
152
|
+
peer === void 0 ? SYNTH_FATAL_MESSAGES[code] : SYNTH_PEER_MESSAGES[peer],
|
|
153
|
+
"cause" in options ? { cause: options.cause } : void 0
|
|
154
|
+
);
|
|
118
155
|
this.name = "SynthError";
|
|
119
156
|
this.code = code;
|
|
157
|
+
if (peer !== void 0) Object.defineProperty(this, "peer", { value: peer, enumerable: true });
|
|
120
158
|
}
|
|
121
159
|
};
|
|
122
160
|
|
|
@@ -232,7 +270,7 @@ function luhnMod10(digits) {
|
|
|
232
270
|
if (d < 0 || d > 9) continue;
|
|
233
271
|
if (double) {
|
|
234
272
|
d *= 2;
|
|
235
|
-
if (d
|
|
273
|
+
if (d >= 10) d -= 9;
|
|
236
274
|
}
|
|
237
275
|
sum += d;
|
|
238
276
|
double = !double;
|
|
@@ -329,7 +367,7 @@ var SYNTHETIC_CITY_NAMES = Object.freeze([
|
|
|
329
367
|
]);
|
|
330
368
|
|
|
331
369
|
// src/safe/providers.ts
|
|
332
|
-
function ssn(rng, block
|
|
370
|
+
function ssn(rng, block) {
|
|
333
371
|
if (block === "advertising") {
|
|
334
372
|
return `987-00-432${String(rng.int(0, 9))}`;
|
|
335
373
|
}
|
|
@@ -456,6 +494,63 @@ var US_STATES = Object.freeze([
|
|
|
456
494
|
"WY"
|
|
457
495
|
]);
|
|
458
496
|
|
|
497
|
+
// src/safe/animal-code.ts
|
|
498
|
+
var ANIMAL_CODE_SYSTEM = "99COSYTE";
|
|
499
|
+
function animalCode(value, text) {
|
|
500
|
+
return Object.freeze({ code: value, text, system: ANIMAL_CODE_SYSTEM });
|
|
501
|
+
}
|
|
502
|
+
function animalSpecies(value, text, breeds) {
|
|
503
|
+
return Object.freeze({ ...animalCode(value, text), breeds: Object.freeze([...breeds]) });
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// src/safe/animal.ts
|
|
507
|
+
var SYNTHETIC_ANIMAL_SPECIES = Object.freeze([
|
|
508
|
+
animalSpecies("DOG", "Dog", [
|
|
509
|
+
animalCode("DOG-LAB", "Labrador Retriever"),
|
|
510
|
+
animalCode("DOG-BGL", "Beagle"),
|
|
511
|
+
animalCode("DOG-MIX", "Mixed breed dog")
|
|
512
|
+
]),
|
|
513
|
+
animalSpecies("CAT", "Cat", [animalCode("CAT-DSH", "Domestic Shorthair"), animalCode("CAT-SIA", "Siamese")]),
|
|
514
|
+
animalSpecies("HORSE", "Horse", [animalCode("HRS-QTR", "Quarter Horse"), animalCode("HRS-TB", "Thoroughbred")]),
|
|
515
|
+
animalSpecies("CATTLE", "Cattle", [animalCode("CTL-HOL", "Holstein"), animalCode("CTL-ANG", "Angus")])
|
|
516
|
+
]);
|
|
517
|
+
var SYNTHETIC_PET_NAMES = Object.freeze([
|
|
518
|
+
"Fixturepaw",
|
|
519
|
+
"Mockwhisker",
|
|
520
|
+
"Stubtail",
|
|
521
|
+
"Seedpup",
|
|
522
|
+
"Testbiscuit",
|
|
523
|
+
"Placepurr",
|
|
524
|
+
"Synthfur",
|
|
525
|
+
"Dummymane",
|
|
526
|
+
"Examplehoof",
|
|
527
|
+
"Fauxfluff",
|
|
528
|
+
"Samplesnout",
|
|
529
|
+
"Voidwag"
|
|
530
|
+
]);
|
|
531
|
+
var MICROCHIP_TEST_PREFIX = "999";
|
|
532
|
+
function petName(rng) {
|
|
533
|
+
return rng.pick(SYNTHETIC_PET_NAMES);
|
|
534
|
+
}
|
|
535
|
+
function animalBreed(rng) {
|
|
536
|
+
const picked = rng.pick(SYNTHETIC_ANIMAL_SPECIES);
|
|
537
|
+
const { breeds, ...bare } = picked;
|
|
538
|
+
return { species: Object.freeze(bare), breed: rng.pick(breeds) };
|
|
539
|
+
}
|
|
540
|
+
function microchip(rng) {
|
|
541
|
+
return `${MICROCHIP_TEST_PREFIX}${rng.digits(12)}`;
|
|
542
|
+
}
|
|
543
|
+
function animalBirthDate(rng, onDate) {
|
|
544
|
+
const year = Number(onDate.slice(0, 4));
|
|
545
|
+
const month = Number(onDate.slice(4, 6)) - 1;
|
|
546
|
+
const day = Number(onDate.slice(6, 8));
|
|
547
|
+
const latest = Date.UTC(year, month, day);
|
|
548
|
+
const earliest = Date.UTC(year - 20, month, day);
|
|
549
|
+
const span = Math.round((latest - earliest) / 864e5);
|
|
550
|
+
const born = new Date(latest - rng.int(0, span) * 864e5);
|
|
551
|
+
return born.toISOString().slice(0, 10).replace(/-/g, "");
|
|
552
|
+
}
|
|
553
|
+
|
|
459
554
|
// src/safe/index.ts
|
|
460
555
|
var safe = Object.freeze({
|
|
461
556
|
ssn,
|
|
@@ -469,20 +564,54 @@ var safe = Object.freeze({
|
|
|
469
564
|
address,
|
|
470
565
|
dateYmd,
|
|
471
566
|
npi,
|
|
472
|
-
dea
|
|
567
|
+
dea,
|
|
568
|
+
petName,
|
|
569
|
+
animalBreed,
|
|
570
|
+
microchip,
|
|
571
|
+
animalBirthDate
|
|
473
572
|
});
|
|
474
573
|
function defaultHost() {
|
|
475
574
|
if (typeof undefined !== "function") return { require: __require, resolve: void 0 };
|
|
476
575
|
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) };
|
|
477
576
|
}
|
|
577
|
+
function isDenoResolveRefusal(error) {
|
|
578
|
+
return error instanceof TypeError && !("code" in error) && error.message === "Invalid arguments";
|
|
579
|
+
}
|
|
478
580
|
function isRequireEsmRefusal(error) {
|
|
479
581
|
return error?.code === "ERR_REQUIRE_ESM";
|
|
480
582
|
}
|
|
583
|
+
function peerPackage(specifier) {
|
|
584
|
+
const name2 = specifier.split("/").slice(0, 2).join("/");
|
|
585
|
+
return Object.hasOwn(SYNTH_PEER_MESSAGES, name2) ? name2 : void 0;
|
|
586
|
+
}
|
|
587
|
+
function isPeerNotFound(error, specifier, peer) {
|
|
588
|
+
const { code, message } = error ?? {};
|
|
589
|
+
if (typeof message !== "string") return false;
|
|
590
|
+
if (code === "ERR_MODULE_NOT_FOUND") return message.startsWith(`Cannot find package '${peer}'`);
|
|
591
|
+
if (code === "MODULE_NOT_FOUND") return message.startsWith(`Cannot find module '${specifier}'`);
|
|
592
|
+
return false;
|
|
593
|
+
}
|
|
481
594
|
function loadPeer(specifier, host) {
|
|
595
|
+
try {
|
|
596
|
+
return loadFrom(specifier, host);
|
|
597
|
+
} catch (error) {
|
|
598
|
+
const peer = peerPackage(specifier);
|
|
599
|
+
if (peer === void 0 || !isPeerNotFound(error, specifier, peer)) throw error;
|
|
600
|
+
throw new SynthError(SYNTH_FATAL_CODES.SYNTH_PEER_NOT_INSTALLED, { peer, cause: error });
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
function loadFrom(specifier, host) {
|
|
482
604
|
if (host.resolve === void 0) return host.require(specifier);
|
|
483
|
-
|
|
605
|
+
let url$1;
|
|
606
|
+
try {
|
|
607
|
+
url$1 = host.resolve(specifier);
|
|
608
|
+
} catch (error) {
|
|
609
|
+
if (!isDenoResolveRefusal(error)) throw error;
|
|
610
|
+
return host.require(specifier);
|
|
611
|
+
}
|
|
612
|
+
if (!url$1.startsWith("file:")) return host.require(specifier);
|
|
484
613
|
try {
|
|
485
|
-
return host.require(
|
|
614
|
+
return host.require(url.fileURLToPath(url$1));
|
|
486
615
|
} catch (error) {
|
|
487
616
|
if (!isRequireEsmRefusal(error)) throw error;
|
|
488
617
|
return host.require(specifier);
|
|
@@ -504,6 +633,20 @@ function seededTimestamp(rng) {
|
|
|
504
633
|
const ss = String(rng.int(0, 59)).padStart(2, "0");
|
|
505
634
|
return `${date}${hh}${mm}${ss}`;
|
|
506
635
|
}
|
|
636
|
+
function shiftTimestamp(timestamp, seconds) {
|
|
637
|
+
const at = new Date(
|
|
638
|
+
Date.UTC(
|
|
639
|
+
Number(timestamp.slice(0, 4)),
|
|
640
|
+
Number(timestamp.slice(4, 6)) - 1,
|
|
641
|
+
Number(timestamp.slice(6, 8)),
|
|
642
|
+
Number(timestamp.slice(8, 10)),
|
|
643
|
+
Number(timestamp.slice(10, 12)),
|
|
644
|
+
Number(timestamp.slice(12, 14)) + seconds
|
|
645
|
+
)
|
|
646
|
+
);
|
|
647
|
+
const pad = (n, width = 2) => String(n).padStart(width, "0");
|
|
648
|
+
return pad(at.getUTCFullYear(), 4) + pad(at.getUTCMonth() + 1) + pad(at.getUTCDate()) + pad(at.getUTCHours()) + pad(at.getUTCMinutes()) + pad(at.getUTCSeconds());
|
|
649
|
+
}
|
|
507
650
|
function mshScaffold(rng, type) {
|
|
508
651
|
const timestamp = seededTimestamp(rng);
|
|
509
652
|
const controlId = `SYNTH${rng.digits(10)}`;
|
|
@@ -574,6 +717,107 @@ function pidSegment(id) {
|
|
|
574
717
|
// PID-19 SSN (digits)
|
|
575
718
|
];
|
|
576
719
|
}
|
|
720
|
+
function hl7Subjects() {
|
|
721
|
+
return ["person", "animal"];
|
|
722
|
+
}
|
|
723
|
+
var MICROCHIP_IDENTIFIER_TYPE = "MCN";
|
|
724
|
+
var OWNER_RELATIONSHIP = Object.freeze({ code: "OWN", text: "Owner", system: "HL70063" });
|
|
725
|
+
function animalIdentity(rng, onDate) {
|
|
726
|
+
const person = safe.name(rng);
|
|
727
|
+
const petName2 = safe.petName(rng);
|
|
728
|
+
const record = safe.identifier(rng, "MR");
|
|
729
|
+
const microchip2 = safe.microchip(rng);
|
|
730
|
+
const { species, breed } = safe.animalBreed(rng);
|
|
731
|
+
const dob = safe.animalBirthDate(rng, onDate);
|
|
732
|
+
const sex = rng.pick(["M", "F"]);
|
|
733
|
+
const address2 = safe.address(rng);
|
|
734
|
+
const phone2 = safe.phone(rng);
|
|
735
|
+
return {
|
|
736
|
+
petName: petName2,
|
|
737
|
+
record,
|
|
738
|
+
microchip: microchip2,
|
|
739
|
+
species,
|
|
740
|
+
breed,
|
|
741
|
+
dob,
|
|
742
|
+
sex,
|
|
743
|
+
owner: { person, address: address2, phone: phone2 }
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
function codedField(value) {
|
|
747
|
+
return componentsField([value.code, value.text, value.system]);
|
|
748
|
+
}
|
|
749
|
+
function animalPidSegment(id) {
|
|
750
|
+
const authority = id.record.assigningAuthority;
|
|
751
|
+
const cx = (value, type) => ({
|
|
752
|
+
components: [value, "", "", authority, type].map((c) => ({ subcomponents: [c] }))
|
|
753
|
+
});
|
|
754
|
+
const identifiers = {
|
|
755
|
+
repetitions: [
|
|
756
|
+
cx(id.record.value, id.record.typeCode),
|
|
757
|
+
cx(id.microchip, MICROCHIP_IDENTIFIER_TYPE)
|
|
758
|
+
],
|
|
759
|
+
isNull: false
|
|
760
|
+
};
|
|
761
|
+
const { person, address: address2, phone: phone2 } = id.owner;
|
|
762
|
+
return [
|
|
763
|
+
"1",
|
|
764
|
+
// PID-1 set id
|
|
765
|
+
"",
|
|
766
|
+
// PID-2
|
|
767
|
+
identifiers,
|
|
768
|
+
// PID-3 CX: record number, then microchip
|
|
769
|
+
"",
|
|
770
|
+
// PID-4
|
|
771
|
+
componentsField([person.family, id.petName]),
|
|
772
|
+
// PID-5 XPN: owner family, pet name
|
|
773
|
+
"",
|
|
774
|
+
// PID-6
|
|
775
|
+
id.dob,
|
|
776
|
+
// PID-7 DOB
|
|
777
|
+
id.sex,
|
|
778
|
+
// PID-8 sex
|
|
779
|
+
"",
|
|
780
|
+
// PID-9
|
|
781
|
+
"",
|
|
782
|
+
// PID-10
|
|
783
|
+
componentsField([address2.street, "", address2.city, address2.state, address2.zip]),
|
|
784
|
+
// PID-11 XAD
|
|
785
|
+
"",
|
|
786
|
+
// PID-12
|
|
787
|
+
phone2,
|
|
788
|
+
// PID-13 phone
|
|
789
|
+
...Array(21).fill(""),
|
|
790
|
+
// PID-14 to PID-34
|
|
791
|
+
codedField(id.species),
|
|
792
|
+
// PID-35 species code (CE)
|
|
793
|
+
codedField(id.breed)
|
|
794
|
+
// PID-36 breed code (CE)
|
|
795
|
+
];
|
|
796
|
+
}
|
|
797
|
+
function ownerNk1Segment(id) {
|
|
798
|
+
const { person, address: address2, phone: phone2 } = id.owner;
|
|
799
|
+
return [
|
|
800
|
+
"1",
|
|
801
|
+
// NK1-1 set id
|
|
802
|
+
componentsField([person.family, person.given]),
|
|
803
|
+
// NK1-2 name
|
|
804
|
+
codedField(OWNER_RELATIONSHIP),
|
|
805
|
+
// NK1-3 relationship (CE)
|
|
806
|
+
componentsField([address2.street, "", address2.city, address2.state, address2.zip]),
|
|
807
|
+
// NK1-4
|
|
808
|
+
phone2
|
|
809
|
+
// NK1-5 phone
|
|
810
|
+
];
|
|
811
|
+
}
|
|
812
|
+
function addSubject(message, rng, subject, timestamp) {
|
|
813
|
+
if (subject === "person") {
|
|
814
|
+
message.addSegment("PID", pidSegment(patientIdentity(rng)));
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
817
|
+
const animal = animalIdentity(rng, timestamp);
|
|
818
|
+
message.addSegment("PID", animalPidSegment(animal));
|
|
819
|
+
message.addSegment("NK1", ownerNk1Segment(animal));
|
|
820
|
+
}
|
|
577
821
|
|
|
578
822
|
// src/select.ts
|
|
579
823
|
function resolveKind(allowed, requested) {
|
|
@@ -585,27 +829,90 @@ function resolveMix(allowed, requested, fallback) {
|
|
|
585
829
|
if (requested === void 0) return fallback;
|
|
586
830
|
return requested.map((entry) => resolveKind(allowed, entry));
|
|
587
831
|
}
|
|
832
|
+
function requireSelection(selection) {
|
|
833
|
+
if (selection.length === 0) throw new SynthError(SYNTH_FATAL_CODES.SYNTH_EMPTY_POOL);
|
|
834
|
+
return selection;
|
|
835
|
+
}
|
|
588
836
|
|
|
589
837
|
// src/hl7/adt.ts
|
|
590
|
-
|
|
838
|
+
function adtTriggers() {
|
|
839
|
+
return ["A01", "A04", "A08", "A02", "A03", "A11", "A13", "A28", "A31"];
|
|
840
|
+
}
|
|
841
|
+
function structureOf(trigger) {
|
|
842
|
+
switch (trigger) {
|
|
843
|
+
case "A02":
|
|
844
|
+
return "ADT_A02";
|
|
845
|
+
case "A03":
|
|
846
|
+
return "ADT_A03";
|
|
847
|
+
case "A11":
|
|
848
|
+
return "ADT_A09";
|
|
849
|
+
case "A13":
|
|
850
|
+
return "ADT_A01";
|
|
851
|
+
case "A28":
|
|
852
|
+
case "A31":
|
|
853
|
+
return "ADT_A05";
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
function ward(room) {
|
|
857
|
+
return componentsField(["SYNTHWARD", String(room).padStart(3, "0"), "01"]);
|
|
858
|
+
}
|
|
859
|
+
function location(rng) {
|
|
860
|
+
return ward(rng.int(1, 999));
|
|
861
|
+
}
|
|
862
|
+
function admittedBefore(rng, timestamp) {
|
|
863
|
+
return shiftTimestamp(timestamp, -rng.int(3600, 14 * 86400));
|
|
864
|
+
}
|
|
591
865
|
function generateAdt(options = {}) {
|
|
592
866
|
const seed = options.seed ?? 0;
|
|
593
|
-
const trigger = resolveKind(
|
|
867
|
+
const trigger = resolveKind(adtTriggers(), options.trigger ?? "A01");
|
|
868
|
+
const subject = resolveKind(hl7Subjects(), options.subject ?? "person");
|
|
594
869
|
const rng = createRng(seed);
|
|
595
|
-
|
|
870
|
+
if (trigger === "A01" || trigger === "A04" || trigger === "A08") {
|
|
871
|
+
const { message: message2, timestamp: timestamp2 } = mshScaffold(rng, `ADT^${trigger}`);
|
|
872
|
+
message2.addSegment("EVN", [trigger, timestamp2]);
|
|
873
|
+
addSubject(message2, rng, subject, timestamp2);
|
|
874
|
+
const patientClass = rng.pick(["I", "O", "E"]);
|
|
875
|
+
message2.addSegment("PV1", [
|
|
876
|
+
"1",
|
|
877
|
+
// PV1-1 set id
|
|
878
|
+
patientClass,
|
|
879
|
+
// PV1-2 patient class
|
|
880
|
+
location(rng)
|
|
881
|
+
// PV1-3 PL
|
|
882
|
+
]);
|
|
883
|
+
return message2;
|
|
884
|
+
}
|
|
885
|
+
const { message, timestamp } = mshScaffold(rng, `ADT^${trigger}^${structureOf(trigger)}`);
|
|
596
886
|
message.addSegment("EVN", [trigger, timestamp]);
|
|
597
|
-
message
|
|
598
|
-
|
|
599
|
-
message.addSegment("PV1", [
|
|
600
|
-
"1",
|
|
601
|
-
// PV1-1 set id
|
|
602
|
-
patientClass,
|
|
603
|
-
// PV1-2 patient class
|
|
604
|
-
componentsField(["SYNTHWARD", String(rng.int(1, 999)).padStart(3, "0"), "01"])
|
|
605
|
-
// PV1-3 PL
|
|
606
|
-
]);
|
|
887
|
+
addSubject(message, rng, subject, timestamp);
|
|
888
|
+
message.addSegment("PV1", visit(rng, trigger, timestamp));
|
|
607
889
|
return message;
|
|
608
890
|
}
|
|
891
|
+
function visit(rng, trigger, timestamp) {
|
|
892
|
+
switch (trigger) {
|
|
893
|
+
case "A02": {
|
|
894
|
+
const room = rng.int(1, 998);
|
|
895
|
+
const priorRoom = room + rng.int(1, 999 - room);
|
|
896
|
+
return ["1", "I", ward(room), "", "", ward(priorRoom)];
|
|
897
|
+
}
|
|
898
|
+
case "A03": {
|
|
899
|
+
const patientClass = rng.pick(["I", "O", "E"]);
|
|
900
|
+
const where = location(rng);
|
|
901
|
+
const admitted = admittedBefore(rng, timestamp);
|
|
902
|
+
return ["1", patientClass, where, ...Array(40).fill(""), admitted, timestamp];
|
|
903
|
+
}
|
|
904
|
+
case "A11":
|
|
905
|
+
return ["1", rng.pick(["I", "O", "E"]), location(rng)];
|
|
906
|
+
case "A13": {
|
|
907
|
+
const where = location(rng);
|
|
908
|
+
const admitted = admittedBefore(rng, timestamp);
|
|
909
|
+
return ["1", "I", where, ...Array(40).fill(""), admitted];
|
|
910
|
+
}
|
|
911
|
+
case "A28":
|
|
912
|
+
case "A31":
|
|
913
|
+
return ["1", "N"];
|
|
914
|
+
}
|
|
915
|
+
}
|
|
609
916
|
|
|
610
917
|
// src/hl7/example-codes.ts
|
|
611
918
|
var EXAMPLE_LAB_OBSERVATIONS = Object.freeze([
|
|
@@ -670,9 +977,10 @@ function obxSegment(rng, setId) {
|
|
|
670
977
|
}
|
|
671
978
|
function generateOru(options = {}) {
|
|
672
979
|
const seed = options.seed ?? 0;
|
|
980
|
+
const subject = resolveKind(hl7Subjects(), options.subject ?? "person");
|
|
673
981
|
const rng = createRng(seed);
|
|
674
|
-
const { message } = mshScaffold(rng, "ORU^R01");
|
|
675
|
-
message
|
|
982
|
+
const { message, timestamp } = mshScaffold(rng, "ORU^R01");
|
|
983
|
+
addSubject(message, rng, subject, timestamp);
|
|
676
984
|
const service = rng.pick(EXAMPLE_ORDER_SERVICES);
|
|
677
985
|
const placer = rng.digits(8);
|
|
678
986
|
const filler = rng.digits(8);
|
|
@@ -863,6 +1171,184 @@ function generateVxu(options = {}) {
|
|
|
863
1171
|
return message;
|
|
864
1172
|
}
|
|
865
1173
|
|
|
1174
|
+
// src/hl7/mdm.ts
|
|
1175
|
+
var DOCUMENT_TYPES = Object.freeze(["CN", "DS", "HP", "PN"]);
|
|
1176
|
+
var NOTE_LINES = Object.freeze([
|
|
1177
|
+
"Synthetic test document for interface testing.",
|
|
1178
|
+
"Synthetic note text: no real patient is described here.",
|
|
1179
|
+
"Synthetic content generated from a seed."
|
|
1180
|
+
]);
|
|
1181
|
+
function generateMdm(options = {}) {
|
|
1182
|
+
const seed = options.seed ?? 0;
|
|
1183
|
+
const rng = createRng(seed);
|
|
1184
|
+
const { message, timestamp } = mshScaffold(rng, "MDM^T02^MDM_T02");
|
|
1185
|
+
message.addSegment("EVN", ["T02", timestamp]);
|
|
1186
|
+
message.addSegment("PID", pidSegment(patientIdentity(rng)));
|
|
1187
|
+
message.addSegment("PV1", ["1", rng.pick(["I", "O", "E"])]);
|
|
1188
|
+
const documentType = rng.pick(DOCUMENT_TYPES);
|
|
1189
|
+
const documentNumber = `SYNTHDOC${rng.digits(10)}`;
|
|
1190
|
+
message.addSegment("TXA", [
|
|
1191
|
+
"1",
|
|
1192
|
+
// TXA-1 set id
|
|
1193
|
+
documentType,
|
|
1194
|
+
// TXA-2 document type
|
|
1195
|
+
"TX",
|
|
1196
|
+
// TXA-3 document content presentation (text)
|
|
1197
|
+
timestamp,
|
|
1198
|
+
// TXA-4 activity date/time
|
|
1199
|
+
...Array(7).fill(""),
|
|
1200
|
+
// TXA-5 to TXA-11
|
|
1201
|
+
componentsField([documentNumber, "COSYTE-SYNTH"]),
|
|
1202
|
+
// TXA-12 unique document number (EI)
|
|
1203
|
+
...Array(4).fill(""),
|
|
1204
|
+
// TXA-13 to TXA-16
|
|
1205
|
+
"DO"
|
|
1206
|
+
// TXA-17 document completion status (documented)
|
|
1207
|
+
]);
|
|
1208
|
+
const lines = rng.int(1, 3);
|
|
1209
|
+
for (let i = 1; i <= lines; i += 1) {
|
|
1210
|
+
message.addSegment("OBX", [
|
|
1211
|
+
String(i),
|
|
1212
|
+
// OBX-1 set id
|
|
1213
|
+
"TX",
|
|
1214
|
+
// OBX-2 value type
|
|
1215
|
+
componentsField(["SYNTHNOTE", "Synthetic note", "99SYN"]),
|
|
1216
|
+
// OBX-3 observation id (local)
|
|
1217
|
+
"",
|
|
1218
|
+
// OBX-4 sub-id
|
|
1219
|
+
rng.pick(NOTE_LINES),
|
|
1220
|
+
// OBX-5 the document text
|
|
1221
|
+
...Array(5).fill(""),
|
|
1222
|
+
// OBX-6 to OBX-10
|
|
1223
|
+
"F"
|
|
1224
|
+
// OBX-11 result status (final)
|
|
1225
|
+
]);
|
|
1226
|
+
}
|
|
1227
|
+
return message;
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
// src/hl7/dft.ts
|
|
1231
|
+
function charges() {
|
|
1232
|
+
return [
|
|
1233
|
+
{ code: "SYNTHCHG01", text: "Synthetic office visit charge" },
|
|
1234
|
+
{ code: "SYNTHCHG02", text: "Synthetic laboratory charge" },
|
|
1235
|
+
{ code: "SYNTHCHG03", text: "Synthetic imaging charge" },
|
|
1236
|
+
{ code: "SYNTHCHG04", text: "Synthetic supply charge" }
|
|
1237
|
+
];
|
|
1238
|
+
}
|
|
1239
|
+
function generateDft(options = {}) {
|
|
1240
|
+
const seed = options.seed ?? 0;
|
|
1241
|
+
const rng = createRng(seed);
|
|
1242
|
+
const { message, timestamp } = mshScaffold(rng, "DFT^P03^DFT_P03");
|
|
1243
|
+
message.addSegment("EVN", ["P03", timestamp]);
|
|
1244
|
+
message.addSegment("PID", pidSegment(patientIdentity(rng)));
|
|
1245
|
+
message.addSegment("PV1", ["1", rng.pick(["I", "O", "E"])]);
|
|
1246
|
+
const transactionId = `SYNTHTXN${rng.digits(8)}`;
|
|
1247
|
+
const charge = rng.pick(charges());
|
|
1248
|
+
const quantity = String(rng.int(1, 3));
|
|
1249
|
+
message.addSegment("FT1", [
|
|
1250
|
+
"1",
|
|
1251
|
+
// FT1-1 set id
|
|
1252
|
+
transactionId,
|
|
1253
|
+
// FT1-2 transaction id
|
|
1254
|
+
"",
|
|
1255
|
+
// FT1-3 transaction batch id
|
|
1256
|
+
timestamp,
|
|
1257
|
+
// FT1-4 transaction date
|
|
1258
|
+
"",
|
|
1259
|
+
// FT1-5 transaction posting date
|
|
1260
|
+
"CG",
|
|
1261
|
+
// FT1-6 transaction type (charge)
|
|
1262
|
+
componentsField([charge.code, charge.text, "99SYN"]),
|
|
1263
|
+
// FT1-7 transaction code (local)
|
|
1264
|
+
"",
|
|
1265
|
+
// FT1-8 transaction description
|
|
1266
|
+
"",
|
|
1267
|
+
// FT1-9 transaction description, alternate
|
|
1268
|
+
quantity
|
|
1269
|
+
// FT1-10 transaction quantity
|
|
1270
|
+
]);
|
|
1271
|
+
return message;
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
// src/hl7/oml.ts
|
|
1275
|
+
function generateOml(options = {}) {
|
|
1276
|
+
const seed = options.seed ?? 0;
|
|
1277
|
+
const rng = createRng(seed);
|
|
1278
|
+
const { message } = mshScaffold(rng, "OML^O21^OML_O21");
|
|
1279
|
+
message.addSegment("PID", pidSegment(patientIdentity(rng)));
|
|
1280
|
+
const service = rng.pick(EXAMPLE_ORDER_SERVICES);
|
|
1281
|
+
const placer = rng.digits(8);
|
|
1282
|
+
const filler = rng.digits(8);
|
|
1283
|
+
const orderedAt = seededTimestamp(rng);
|
|
1284
|
+
message.addSegment("ORC", [
|
|
1285
|
+
"NW",
|
|
1286
|
+
// ORC-1 order control (new order)
|
|
1287
|
+
placer,
|
|
1288
|
+
// ORC-2 placer order number
|
|
1289
|
+
filler,
|
|
1290
|
+
// ORC-3 filler order number
|
|
1291
|
+
...Array(5).fill(""),
|
|
1292
|
+
// ORC-4 to ORC-8
|
|
1293
|
+
orderedAt
|
|
1294
|
+
// ORC-9 date/time of transaction
|
|
1295
|
+
]);
|
|
1296
|
+
message.addSegment("OBR", [
|
|
1297
|
+
"1",
|
|
1298
|
+
// OBR-1 set id
|
|
1299
|
+
placer,
|
|
1300
|
+
// OBR-2 placer order number (matches ORC)
|
|
1301
|
+
filler,
|
|
1302
|
+
// OBR-3 filler order number (matches ORC)
|
|
1303
|
+
componentsField([service.code, service.text, service.system])
|
|
1304
|
+
// OBR-4 universal service id
|
|
1305
|
+
]);
|
|
1306
|
+
return message;
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
// src/hl7/ack.ts
|
|
1310
|
+
function generateAck(options = {}) {
|
|
1311
|
+
const seed = options.seed ?? 0;
|
|
1312
|
+
const allowed = ["AA", "AE", "AR"];
|
|
1313
|
+
const code = resolveKind(allowed, options.code ?? "AA");
|
|
1314
|
+
const inbound = options.inbound ?? generateAdt({ seed });
|
|
1315
|
+
const inboundControlId = inbound.get("MSH.10") ?? "";
|
|
1316
|
+
if (inboundControlId === "") throw new SynthError(SYNTH_FATAL_CODES.SYNTH_ACK_UNCORRELATED);
|
|
1317
|
+
const rng = createRng(seed);
|
|
1318
|
+
const delaySeconds = rng.int(1, 59);
|
|
1319
|
+
const controlId = `SYNTHACK${rng.digits(10)}`;
|
|
1320
|
+
const inboundTime = String(inbound.get("MSH.7"));
|
|
1321
|
+
const timestamp = /^\d{14}$/.test(inboundTime) ? shiftTimestamp(inboundTime, delaySeconds) : seededTimestamp(rng);
|
|
1322
|
+
const trigger = inbound.get("MSH.9.2") ?? "";
|
|
1323
|
+
const message = hl7Peer().buildMessage({
|
|
1324
|
+
type: trigger === "" ? "ACK" : `ACK^${trigger}^ACK`,
|
|
1325
|
+
sendingApp: inbound.get("MSH.5") ?? "",
|
|
1326
|
+
sendingFacility: inbound.get("MSH.6") ?? "",
|
|
1327
|
+
receivingApp: inbound.get("MSH.3") ?? "",
|
|
1328
|
+
receivingFacility: inbound.get("MSH.4") ?? "",
|
|
1329
|
+
controlId,
|
|
1330
|
+
timestamp,
|
|
1331
|
+
version: inbound.get("MSH.12") ?? "2.5",
|
|
1332
|
+
// MSH-11 processing ID `T` (HL7 table 0103: training): an acknowledgment of test data is test
|
|
1333
|
+
// data, so it never echoes a `P` from the inbound message.
|
|
1334
|
+
processingId: "T"
|
|
1335
|
+
});
|
|
1336
|
+
message.addSegment("MSA", [code, inboundControlId]);
|
|
1337
|
+
if (code !== "AA") {
|
|
1338
|
+
message.addSegment("ERR", [
|
|
1339
|
+
"",
|
|
1340
|
+
// ERR-1 error code and location (backward compatible only)
|
|
1341
|
+
"",
|
|
1342
|
+
// ERR-2 error location
|
|
1343
|
+
componentsField(["207", "Application internal error", "HL70357"]),
|
|
1344
|
+
// ERR-3 HL7 error code
|
|
1345
|
+
"E"
|
|
1346
|
+
// ERR-4 severity (error)
|
|
1347
|
+
]);
|
|
1348
|
+
}
|
|
1349
|
+
return message;
|
|
1350
|
+
}
|
|
1351
|
+
|
|
866
1352
|
// src/hl7/round-trip.ts
|
|
867
1353
|
function roundTrip(message) {
|
|
868
1354
|
const content = message.toString();
|
|
@@ -894,7 +1380,7 @@ function defineSynthProfile(spec) {
|
|
|
894
1380
|
name: spec.name,
|
|
895
1381
|
...spec.givenNames ? { givenNames: Object.freeze([...spec.givenNames]) } : {},
|
|
896
1382
|
...spec.familyNames ? { familyNames: Object.freeze([...spec.familyNames]) } : {},
|
|
897
|
-
quirks: Object.freeze([...spec.quirks
|
|
1383
|
+
...spec.quirks !== void 0 ? { quirks: Object.freeze([...spec.quirks]) } : {}
|
|
898
1384
|
});
|
|
899
1385
|
}
|
|
900
1386
|
|
|
@@ -936,6 +1422,7 @@ function assertIntendedWarnings(intendedWarnings, bareWarnings) {
|
|
|
936
1422
|
}
|
|
937
1423
|
}
|
|
938
1424
|
function validateProfileQuirks(profile, registry, format) {
|
|
1425
|
+
if (profile.quirks === void 0) return Object.keys(registry);
|
|
939
1426
|
for (const name2 of profile.quirks) resolveQuirk(registry, format, name2);
|
|
940
1427
|
return profile.quirks;
|
|
941
1428
|
}
|
|
@@ -1049,8 +1536,9 @@ var ALL_HL7_QUIRKS = Object.freeze(
|
|
|
1049
1536
|
Object.keys(HL7_QUIRKS)
|
|
1050
1537
|
);
|
|
1051
1538
|
function hl7QuirkCorpus(options) {
|
|
1052
|
-
const
|
|
1053
|
-
|
|
1539
|
+
const names = requireSelection(
|
|
1540
|
+
options.profile?.quirks !== void 0 ? validateProfileQuirks(options.profile, HL7_QUIRKS, "hl7v2") : options.quirks ?? ALL_HL7_QUIRKS
|
|
1541
|
+
);
|
|
1054
1542
|
for (const name2 of names) resolveQuirk(HL7_QUIRKS, "hl7v2", name2);
|
|
1055
1543
|
const kind = options.kind ?? "ORU^R01";
|
|
1056
1544
|
const count = options.count ?? names.length;
|
|
@@ -1074,19 +1562,27 @@ var hl7QuirkProfile = defineSynthProfile({
|
|
|
1074
1562
|
});
|
|
1075
1563
|
|
|
1076
1564
|
// src/hl7/index.ts
|
|
1077
|
-
var
|
|
1565
|
+
var HL7_MESSAGE_KINDS = Object.freeze([
|
|
1078
1566
|
"ADT^A01",
|
|
1079
1567
|
"ADT^A04",
|
|
1080
1568
|
"ADT^A08",
|
|
1081
1569
|
"ORU^R01",
|
|
1082
1570
|
"ORM^O01",
|
|
1083
1571
|
"SIU^S12",
|
|
1084
|
-
"VXU^V04"
|
|
1572
|
+
"VXU^V04",
|
|
1573
|
+
"ACK",
|
|
1574
|
+
"ADT^A02",
|
|
1575
|
+
"ADT^A03",
|
|
1576
|
+
"ADT^A11",
|
|
1577
|
+
"ADT^A13",
|
|
1578
|
+
"ADT^A28",
|
|
1579
|
+
"ADT^A31",
|
|
1580
|
+
"MDM^T02",
|
|
1581
|
+
"DFT^P03",
|
|
1582
|
+
"OML^O21"
|
|
1085
1583
|
]);
|
|
1086
|
-
var DEFAULT_MIX = ALL_KINDS;
|
|
1087
|
-
var ADT_TRIGGERS2 = Object.freeze(["A01", "A04", "A08"]);
|
|
1088
1584
|
function generateHl7(kind, seed) {
|
|
1089
|
-
switch (resolveKind(
|
|
1585
|
+
switch (resolveKind(HL7_MESSAGE_KINDS, kind)) {
|
|
1090
1586
|
case "ADT^A01":
|
|
1091
1587
|
return generateAdt({ seed, trigger: "A01" });
|
|
1092
1588
|
case "ADT^A04":
|
|
@@ -1101,16 +1597,42 @@ function generateHl7(kind, seed) {
|
|
|
1101
1597
|
return generateSiu({ seed });
|
|
1102
1598
|
case "VXU^V04":
|
|
1103
1599
|
return generateVxu({ seed });
|
|
1600
|
+
case "ACK":
|
|
1601
|
+
return generateAck({ seed });
|
|
1602
|
+
case "ADT^A02":
|
|
1603
|
+
return generateAdt({ seed, trigger: "A02" });
|
|
1604
|
+
case "ADT^A03":
|
|
1605
|
+
return generateAdt({ seed, trigger: "A03" });
|
|
1606
|
+
case "ADT^A11":
|
|
1607
|
+
return generateAdt({ seed, trigger: "A11" });
|
|
1608
|
+
case "ADT^A13":
|
|
1609
|
+
return generateAdt({ seed, trigger: "A13" });
|
|
1610
|
+
case "ADT^A28":
|
|
1611
|
+
return generateAdt({ seed, trigger: "A28" });
|
|
1612
|
+
case "ADT^A31":
|
|
1613
|
+
return generateAdt({ seed, trigger: "A31" });
|
|
1614
|
+
case "MDM^T02":
|
|
1615
|
+
return generateMdm({ seed });
|
|
1616
|
+
case "DFT^P03":
|
|
1617
|
+
return generateDft({ seed });
|
|
1618
|
+
case "OML^O21":
|
|
1619
|
+
return generateOml({ seed });
|
|
1104
1620
|
}
|
|
1105
1621
|
}
|
|
1106
1622
|
function hl7Corpus(options) {
|
|
1107
1623
|
const { seed, count = 1, verify = true } = options;
|
|
1108
|
-
const kinds =
|
|
1109
|
-
|
|
1110
|
-
|
|
1624
|
+
const kinds = requireSelection(
|
|
1625
|
+
options.triggers !== void 0 ? options.triggers.map(
|
|
1626
|
+
(t) => `ADT^${resolveKind(adtTriggers(), t)}`
|
|
1627
|
+
) : (
|
|
1628
|
+
// The default mix is the first seven kinds: those added since are not in it, so a seed's
|
|
1629
|
+
// default corpus keeps the bytes it had.
|
|
1630
|
+
resolveMix(HL7_MESSAGE_KINDS, options.mix, HL7_MESSAGE_KINDS.slice(0, 7))
|
|
1631
|
+
)
|
|
1632
|
+
);
|
|
1111
1633
|
const seedStream = createRng(seed);
|
|
1112
1634
|
const artifacts = Array.from({ length: count }, (_unused, i) => {
|
|
1113
|
-
const kind = kinds[i % kinds.length]
|
|
1635
|
+
const kind = kinds[i % kinds.length];
|
|
1114
1636
|
const messageSeed = seedStream.nextUint32();
|
|
1115
1637
|
const rt = hl7CorpusArtifact(generateHl7(kind, messageSeed), verify);
|
|
1116
1638
|
return {
|
|
@@ -1126,11 +1648,20 @@ function hl7Corpus(options) {
|
|
|
1126
1648
|
exports.EXAMPLE_LAB_OBSERVATIONS = EXAMPLE_LAB_OBSERVATIONS;
|
|
1127
1649
|
exports.EXAMPLE_ORDER_SERVICES = EXAMPLE_ORDER_SERVICES;
|
|
1128
1650
|
exports.EXAMPLE_VACCINES = EXAMPLE_VACCINES;
|
|
1651
|
+
exports.HL7_MESSAGE_KINDS = HL7_MESSAGE_KINDS;
|
|
1129
1652
|
exports.HL7_QUIRKS = HL7_QUIRKS;
|
|
1653
|
+
exports.MICROCHIP_IDENTIFIER_TYPE = MICROCHIP_IDENTIFIER_TYPE;
|
|
1654
|
+
exports.OWNER_RELATIONSHIP = OWNER_RELATIONSHIP;
|
|
1655
|
+
exports.animalIdentity = animalIdentity;
|
|
1656
|
+
exports.animalPidSegment = animalPidSegment;
|
|
1130
1657
|
exports.componentsField = componentsField;
|
|
1658
|
+
exports.generateAck = generateAck;
|
|
1131
1659
|
exports.generateAdt = generateAdt;
|
|
1660
|
+
exports.generateDft = generateDft;
|
|
1132
1661
|
exports.generateHl7 = generateHl7;
|
|
1133
1662
|
exports.generateHl7Quirk = generateHl7Quirk;
|
|
1663
|
+
exports.generateMdm = generateMdm;
|
|
1664
|
+
exports.generateOml = generateOml;
|
|
1134
1665
|
exports.generateOrm = generateOrm;
|
|
1135
1666
|
exports.generateOru = generateOru;
|
|
1136
1667
|
exports.generateSiu = generateSiu;
|
|
@@ -1140,6 +1671,7 @@ exports.hl7QuirkCorpus = hl7QuirkCorpus;
|
|
|
1140
1671
|
exports.hl7QuirkProfile = hl7QuirkProfile;
|
|
1141
1672
|
exports.hl7QuirkRoundTrip = hl7QuirkRoundTrip;
|
|
1142
1673
|
exports.mshScaffold = mshScaffold;
|
|
1674
|
+
exports.ownerNk1Segment = ownerNk1Segment;
|
|
1143
1675
|
exports.patientIdentity = patientIdentity;
|
|
1144
1676
|
exports.pidSegment = pidSegment;
|
|
1145
1677
|
exports.roundTrip = roundTrip;
|