@cosyte/synth 0.1.5 → 0.1.6
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 +12 -0
- package/dist/astm/index.cjs +55 -18
- 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 +54 -18
- 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 +207 -118
- package/dist/deid/index.cjs.map +1 -1
- package/dist/deid/index.mjs +194 -106
- 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 +74 -22
- 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 +73 -22
- package/dist/ncpdp/index.mjs.map +1 -1
- package/dist/x12/index.cjs +65 -17
- package/dist/x12/index.cjs.map +1 -1
- package/dist/x12/index.d.cts +6 -0
- package/dist/x12/index.d.ts +6 -0
- package/dist/x12/index.mjs +64 -17
- package/dist/x12/index.mjs.map +1 -1
- package/package.json +20 -15
package/dist/ncpdp/index.d.cts
CHANGED
|
@@ -158,6 +158,7 @@ declare function generateB3(options: GenerateTelecomOptions): string;
|
|
|
158
158
|
*
|
|
159
159
|
* @module
|
|
160
160
|
*/
|
|
161
|
+
|
|
161
162
|
/** The verdict of one round-trip through `@cosyte/ncpdp`. */
|
|
162
163
|
interface RoundTripResult {
|
|
163
164
|
/** The serialized NCPDP wire text (the serializer's own conservative emit). */
|
|
@@ -412,6 +413,12 @@ interface NcpdpCorpusOptions {
|
|
|
412
413
|
readonly count?: number;
|
|
413
414
|
/** The transaction kinds to cycle through. Defaults to one of each. */
|
|
414
415
|
readonly mix?: readonly NcpdpCorpusKind[];
|
|
416
|
+
/**
|
|
417
|
+
* Whether each artifact is read back through its parser and the parser's findings recorded as its
|
|
418
|
+
* `warnings`. Defaults to `true`. `false` skips the read, a large share of a corpus's time; every
|
|
419
|
+
* artifact's `warnings` is then empty without having been checked.
|
|
420
|
+
*/
|
|
421
|
+
readonly verify?: boolean;
|
|
415
422
|
}
|
|
416
423
|
/**
|
|
417
424
|
* Build a reproducible {@link Corpus} of spec-clean NCPDP transactions. Each transaction is generated
|
package/dist/ncpdp/index.d.ts
CHANGED
|
@@ -158,6 +158,7 @@ declare function generateB3(options: GenerateTelecomOptions): string;
|
|
|
158
158
|
*
|
|
159
159
|
* @module
|
|
160
160
|
*/
|
|
161
|
+
|
|
161
162
|
/** The verdict of one round-trip through `@cosyte/ncpdp`. */
|
|
162
163
|
interface RoundTripResult {
|
|
163
164
|
/** The serialized NCPDP wire text (the serializer's own conservative emit). */
|
|
@@ -412,6 +413,12 @@ interface NcpdpCorpusOptions {
|
|
|
412
413
|
readonly count?: number;
|
|
413
414
|
/** The transaction kinds to cycle through. Defaults to one of each. */
|
|
414
415
|
readonly mix?: readonly NcpdpCorpusKind[];
|
|
416
|
+
/**
|
|
417
|
+
* Whether each artifact is read back through its parser and the parser's findings recorded as its
|
|
418
|
+
* `warnings`. Defaults to `true`. `false` skips the read, a large share of a corpus's time; every
|
|
419
|
+
* artifact's `warnings` is then empty without having been checked.
|
|
420
|
+
*/
|
|
421
|
+
readonly verify?: boolean;
|
|
415
422
|
}
|
|
416
423
|
/**
|
|
417
424
|
* Build a reproducible {@link Corpus} of spec-clean NCPDP transactions. Each transaction is generated
|
package/dist/ncpdp/index.mjs
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { createRequire } from 'module';
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
|
|
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
|
+
});
|
|
4
10
|
|
|
5
11
|
// src/rng/splitmix32.ts
|
|
6
12
|
function splitmix32(seed) {
|
|
@@ -150,6 +156,7 @@ function createRng(seed) {
|
|
|
150
156
|
}
|
|
151
157
|
|
|
152
158
|
// src/corpus.ts
|
|
159
|
+
var UNCHECKED = Object.freeze([]);
|
|
153
160
|
function makeCorpus(seed, artifacts, quirks = []) {
|
|
154
161
|
const counts = {};
|
|
155
162
|
const formats = /* @__PURE__ */ new Set();
|
|
@@ -528,6 +535,30 @@ var EXAMPLE_SIG_TEXT = Object.freeze([
|
|
|
528
535
|
"Inhale 2 puffs by mouth every 4 to 6 hours as needed"
|
|
529
536
|
]);
|
|
530
537
|
var DAW_CODES = Object.freeze(["0", "1", "2"]);
|
|
538
|
+
function defaultHost() {
|
|
539
|
+
if (typeof import.meta.resolve !== "function") return { require: __require, resolve: void 0 };
|
|
540
|
+
return { require: createRequire(import.meta.url), resolve: (s) => import.meta.resolve(s) };
|
|
541
|
+
}
|
|
542
|
+
function isRequireEsmRefusal(error) {
|
|
543
|
+
return error?.code === "ERR_REQUIRE_ESM";
|
|
544
|
+
}
|
|
545
|
+
function loadPeer(specifier, host) {
|
|
546
|
+
if (host.resolve === void 0) return host.require(specifier);
|
|
547
|
+
const entry = fileURLToPath(host.resolve(specifier));
|
|
548
|
+
try {
|
|
549
|
+
return host.require(entry);
|
|
550
|
+
} catch (error) {
|
|
551
|
+
if (!isRequireEsmRefusal(error)) throw error;
|
|
552
|
+
return host.require(specifier);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
function lazyPeer(specifier, host) {
|
|
556
|
+
let loaded;
|
|
557
|
+
return () => loaded ??= loadPeer(specifier, defaultHost());
|
|
558
|
+
}
|
|
559
|
+
var ncpdpScriptPeer = lazyPeer("@cosyte/ncpdp/script");
|
|
560
|
+
var ncpdpTelecomPeer = lazyPeer("@cosyte/ncpdp/telecom");
|
|
561
|
+
var ncpdpCommonPeer = lazyPeer("@cosyte/ncpdp/common");
|
|
531
562
|
|
|
532
563
|
// src/ncpdp/script.ts
|
|
533
564
|
var SCRIPT_VERSION = "2017071";
|
|
@@ -558,13 +589,13 @@ function medicationModel(rng, routing) {
|
|
|
558
589
|
const written = `${routing.date.slice(0, 4)}-${routing.date.slice(4, 6)}-${routing.date.slice(6, 8)}`;
|
|
559
590
|
return {
|
|
560
591
|
description: drug.description,
|
|
561
|
-
coded: { productCode: codedValue(drug.ndc, "ND") },
|
|
592
|
+
coded: { productCode: ncpdpCommonPeer().codedValue(drug.ndc, "ND") },
|
|
562
593
|
quantity: {
|
|
563
|
-
value: decimalValue(String(rng.int(30, 90))),
|
|
594
|
+
value: ncpdpCommonPeer().decimalValue(String(rng.int(30, 90))),
|
|
564
595
|
unitOfMeasure: drug.form,
|
|
565
596
|
codeListQualifier: "38"
|
|
566
597
|
},
|
|
567
|
-
daysSupply: decimalValue(String(rng.pick([30, 60, 90]))),
|
|
598
|
+
daysSupply: ncpdpCommonPeer().decimalValue(String(rng.pick([30, 60, 90]))),
|
|
568
599
|
numberOfRefills: String(rng.int(0, 5)),
|
|
569
600
|
substitutions: rng.pick(["0", "1"]),
|
|
570
601
|
writtenDate: written,
|
|
@@ -588,14 +619,14 @@ function generateNewRx(options) {
|
|
|
588
619
|
const pharmacy = pharmacyModel(rng);
|
|
589
620
|
const prescriber = prescriberModel(rng);
|
|
590
621
|
const medication = medicationModel(rng, routing);
|
|
591
|
-
const message = buildNewRx({
|
|
622
|
+
const message = ncpdpScriptPeer().buildNewRx({
|
|
592
623
|
header: headerModel(routing),
|
|
593
624
|
patient,
|
|
594
625
|
pharmacy,
|
|
595
626
|
prescriber,
|
|
596
627
|
medication
|
|
597
628
|
});
|
|
598
|
-
return serializeScript(message);
|
|
629
|
+
return ncpdpScriptPeer().serializeScript(message);
|
|
599
630
|
}
|
|
600
631
|
function lifecycleFields(rng) {
|
|
601
632
|
const routing = ncpdpScriptRouting(rng);
|
|
@@ -612,14 +643,20 @@ function generateRxRenewalRequest(options) {
|
|
|
612
643
|
const rng = createRng(options.seed);
|
|
613
644
|
const { header: header2, ...fields } = lifecycleFields(rng);
|
|
614
645
|
const body = { kind: "RxRenewalRequest", ...fields };
|
|
615
|
-
return serializeScript(
|
|
646
|
+
return ncpdpScriptPeer().serializeScript(
|
|
647
|
+
new (ncpdpScriptPeer()).ScriptMessage({ header: header2, body, warnings: [] })
|
|
648
|
+
);
|
|
616
649
|
}
|
|
617
650
|
function generateRxChangeRequest(options) {
|
|
618
651
|
const rng = createRng(options.seed);
|
|
619
652
|
const { header: header2, ...fields } = lifecycleFields(rng);
|
|
620
653
|
const body = { kind: "RxChangeRequest", ...fields };
|
|
621
|
-
return serializeScript(
|
|
654
|
+
return ncpdpScriptPeer().serializeScript(
|
|
655
|
+
new (ncpdpScriptPeer()).ScriptMessage({ header: header2, body, warnings: [] })
|
|
656
|
+
);
|
|
622
657
|
}
|
|
658
|
+
|
|
659
|
+
// src/ncpdp/telecom.ts
|
|
623
660
|
var SYNTHETIC_BIN = "999999";
|
|
624
661
|
function digitsOnly(value) {
|
|
625
662
|
return value.replace(/\D/g, "");
|
|
@@ -719,7 +756,9 @@ function generateTelecom(code, options) {
|
|
|
719
756
|
prescriberSegment(rng),
|
|
720
757
|
claimSegment(rng, false)
|
|
721
758
|
];
|
|
722
|
-
return serializeTelecom(
|
|
759
|
+
return ncpdpTelecomPeer().serializeTelecom(
|
|
760
|
+
ncpdpTelecomPeer().buildTelecomRequest({ header: head, segments })
|
|
761
|
+
);
|
|
723
762
|
}
|
|
724
763
|
function generateB1(options) {
|
|
725
764
|
return generateTelecom("B1", options);
|
|
@@ -730,18 +769,30 @@ function generateB2(options) {
|
|
|
730
769
|
function generateB3(options) {
|
|
731
770
|
return generateTelecom("B3", options);
|
|
732
771
|
}
|
|
772
|
+
|
|
773
|
+
// src/ncpdp/round-trip.ts
|
|
733
774
|
function scriptRoundTrip(xml) {
|
|
734
|
-
const message = parseScript(xml);
|
|
775
|
+
const message = ncpdpScriptPeer().parseScript(xml);
|
|
735
776
|
const warnings = message.warnings.map((w) => String(w.code));
|
|
736
|
-
const byteStable = serializeScript(message) === xml;
|
|
777
|
+
const byteStable = ncpdpScriptPeer().serializeScript(message) === xml;
|
|
737
778
|
return { content: xml, warnings, byteStable, specClean: warnings.length === 0 && byteStable };
|
|
738
779
|
}
|
|
739
780
|
function telecomRoundTrip(wire) {
|
|
740
|
-
const transaction = parseTelecom(wire);
|
|
781
|
+
const transaction = ncpdpTelecomPeer().parseTelecom(wire);
|
|
741
782
|
const warnings = transaction.warnings.map((w) => String(w.code));
|
|
742
|
-
const byteStable = serializeTelecom(transaction) === wire;
|
|
783
|
+
const byteStable = ncpdpTelecomPeer().serializeTelecom(transaction) === wire;
|
|
743
784
|
return { content: wire, warnings, byteStable, specClean: warnings.length === 0 && byteStable };
|
|
744
785
|
}
|
|
786
|
+
function scriptCorpusArtifact(xml, verify) {
|
|
787
|
+
if (!verify) return { content: xml, warnings: UNCHECKED };
|
|
788
|
+
const warnings = ncpdpScriptPeer().parseScript(xml).warnings.map((w) => String(w.code));
|
|
789
|
+
return { content: xml, warnings };
|
|
790
|
+
}
|
|
791
|
+
function telecomCorpusArtifact(wire, verify) {
|
|
792
|
+
if (!verify) return { content: wire, warnings: UNCHECKED };
|
|
793
|
+
const warnings = ncpdpTelecomPeer().parseTelecom(wire).warnings.map((w) => String(w.code));
|
|
794
|
+
return { content: wire, warnings };
|
|
795
|
+
}
|
|
745
796
|
|
|
746
797
|
// src/select.ts
|
|
747
798
|
function resolveKind(allowed, requested) {
|
|
@@ -764,29 +815,29 @@ var ALL_KINDS = Object.freeze([
|
|
|
764
815
|
"B3"
|
|
765
816
|
]);
|
|
766
817
|
var DEFAULT_MIX = ALL_KINDS;
|
|
767
|
-
function generateKind(kind, seed) {
|
|
818
|
+
function generateKind(kind, seed, verify) {
|
|
768
819
|
switch (kind) {
|
|
769
820
|
case "NewRx":
|
|
770
|
-
return
|
|
821
|
+
return scriptCorpusArtifact(generateNewRx({ seed }), verify);
|
|
771
822
|
case "RxRenewalRequest":
|
|
772
|
-
return
|
|
823
|
+
return scriptCorpusArtifact(generateRxRenewalRequest({ seed }), verify);
|
|
773
824
|
case "RxChangeRequest":
|
|
774
|
-
return
|
|
825
|
+
return scriptCorpusArtifact(generateRxChangeRequest({ seed }), verify);
|
|
775
826
|
case "B1":
|
|
776
827
|
case "B2":
|
|
777
828
|
case "B3":
|
|
778
|
-
return
|
|
829
|
+
return telecomCorpusArtifact(generateTelecom(kind, { seed }), verify);
|
|
779
830
|
}
|
|
780
831
|
}
|
|
781
832
|
function ncpdpCorpus(options) {
|
|
782
|
-
const { seed } = options;
|
|
833
|
+
const { seed, verify = true } = options;
|
|
783
834
|
const mix = resolveMix(ALL_KINDS, options.mix, DEFAULT_MIX);
|
|
784
835
|
const count = options.count ?? mix.length;
|
|
785
836
|
const seedStream = createRng(seed);
|
|
786
837
|
const artifacts = Array.from({ length: count }, (_unused, i) => {
|
|
787
838
|
const kind = mix[i % mix.length] ?? "NewRx";
|
|
788
839
|
const txSeed = seedStream.nextUint32();
|
|
789
|
-
const rt = generateKind(kind, txSeed);
|
|
840
|
+
const rt = generateKind(kind, txSeed, verify);
|
|
790
841
|
return {
|
|
791
842
|
format: "ncpdp",
|
|
792
843
|
kind,
|