@cosyte/synth 0.0.3 → 0.0.5
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 +335 -0
- package/README.md +6 -2
- package/dist/astm/index.cjs +83 -42
- package/dist/astm/index.cjs.map +1 -1
- package/dist/astm/index.d.cts +1 -1
- package/dist/astm/index.d.ts +1 -1
- package/dist/astm/index.mjs +83 -42
- package/dist/astm/index.mjs.map +1 -1
- package/dist/ccda/index.cjs +89 -44
- package/dist/ccda/index.cjs.map +1 -1
- package/dist/ccda/index.d.cts +5 -3
- package/dist/ccda/index.d.ts +5 -3
- package/dist/ccda/index.mjs +89 -44
- package/dist/ccda/index.mjs.map +1 -1
- package/dist/deid/index.cjs +92 -13
- package/dist/deid/index.cjs.map +1 -1
- package/dist/deid/index.d.cts +1 -1
- package/dist/deid/index.d.ts +1 -1
- package/dist/deid/index.mjs +93 -14
- package/dist/deid/index.mjs.map +1 -1
- package/dist/fhir/index.cjs +78 -5
- package/dist/fhir/index.cjs.map +1 -1
- package/dist/fhir/index.mjs +78 -5
- package/dist/fhir/index.mjs.map +1 -1
- package/dist/hl7/index.cjs +89 -41
- package/dist/hl7/index.cjs.map +1 -1
- package/dist/hl7/index.d.cts +1 -1
- package/dist/hl7/index.d.ts +1 -1
- package/dist/hl7/index.mjs +89 -41
- package/dist/hl7/index.mjs.map +1 -1
- package/dist/index.cjs +91 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +126 -8
- package/dist/index.d.ts +126 -8
- package/dist/index.mjs +89 -41
- package/dist/index.mjs.map +1 -1
- package/dist/ncpdp/index.cjs +56 -4
- package/dist/ncpdp/index.cjs.map +1 -1
- package/dist/ncpdp/index.mjs +56 -4
- package/dist/ncpdp/index.mjs.map +1 -1
- package/dist/{quirk-JLyO1Ncj.d.ts → quirk-C9t9CkPS.d.ts} +17 -6
- package/dist/{quirk-DmkgoZdh.d.cts → quirk-DYMDojVw.d.cts} +17 -6
- package/dist/x12/index.cjs +82 -13
- package/dist/x12/index.cjs.map +1 -1
- package/dist/x12/index.d.cts +2 -1
- package/dist/x12/index.d.ts +2 -1
- package/dist/x12/index.mjs +83 -14
- package/dist/x12/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/astm/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { S as SyntheticName, R as Rng, C as Corpus } from '../providers-OLz3zAc-.cjs';
|
|
2
|
-
import { Q as QuirkDescriptor, S as SynthProfile, a as QuirkArtifact, b as QuirkRoundTripResult } from '../quirk-
|
|
2
|
+
import { Q as QuirkDescriptor, S as SynthProfile, a as QuirkArtifact, b as QuirkRoundTripResult } from '../quirk-DYMDojVw.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Spec-clean ASTM (E1394 / CLSI LIS02) message generation — the `H`/`P`/`O`/`R`/`C`/`L` record report —
|
package/dist/astm/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { S as SyntheticName, R as Rng, C as Corpus } from '../providers-OLz3zAc-.js';
|
|
2
|
-
import { Q as QuirkDescriptor, S as SynthProfile, a as QuirkArtifact, b as QuirkRoundTripResult } from '../quirk-
|
|
2
|
+
import { Q as QuirkDescriptor, S as SynthProfile, a as QuirkArtifact, b as QuirkRoundTripResult } from '../quirk-C9t9CkPS.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Spec-clean ASTM (E1394 / CLSI LIS02) message generation — the `H`/`P`/`O`/`R`/`C`/`L` record report —
|
package/dist/astm/index.mjs
CHANGED
|
@@ -29,6 +29,63 @@ function sfc32Next(s) {
|
|
|
29
29
|
return t >>> 0;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
// src/codes.ts
|
|
33
|
+
var SYNTH_FATAL_CODES = {
|
|
34
|
+
/**
|
|
35
|
+
* A vendor quirk was requested that the target format's profile system does not support. Fatal —
|
|
36
|
+
* never a silent no-op and never a fabricated quirk.
|
|
37
|
+
*/
|
|
38
|
+
SYNTH_UNSUPPORTED_QUIRK: "SYNTH_UNSUPPORTED_QUIRK",
|
|
39
|
+
/**
|
|
40
|
+
* A quirk transform found no structural anchor to mutate, so the fixture would not carry the
|
|
41
|
+
* deviation it is labelled with. Fatal — a golden file that lies about its parser verdict is worse
|
|
42
|
+
* than no golden file.
|
|
43
|
+
*/
|
|
44
|
+
SYNTH_QUIRK_ANCHOR_ABSENT: "SYNTH_QUIRK_ANCHOR_ABSENT",
|
|
45
|
+
/**
|
|
46
|
+
* A bare parse of a freshly-generated quirk artifact did not produce exactly the declared intended
|
|
47
|
+
* warning code(s). Fatal — never emit a mislabeled fixture.
|
|
48
|
+
*/
|
|
49
|
+
SYNTH_INTENDED_WARNING_MISMATCH: "SYNTH_INTENDED_WARNING_MISMATCH",
|
|
50
|
+
/** An integer range was requested with its maximum below its minimum. Fatal. */
|
|
51
|
+
SYNTH_INVALID_RANGE: "SYNTH_INVALID_RANGE",
|
|
52
|
+
/** A value was drawn from an empty pool. Fatal — never a fabricated substitute. */
|
|
53
|
+
SYNTH_EMPTY_POOL: "SYNTH_EMPTY_POOL",
|
|
54
|
+
/** A `defineSynthProfile` spec was not usable (a missing or blank `name`). Fatal. */
|
|
55
|
+
SYNTH_INVALID_PROFILE: "SYNTH_INVALID_PROFILE",
|
|
56
|
+
/**
|
|
57
|
+
* A caller-supplied selector (a message kind, a document type, a corpus mix entry, a claim
|
|
58
|
+
* variant, a Bundle type, a resource profile) is not in the closed set that governs it. Fatal —
|
|
59
|
+
* see `resolveKind`: a selector union is erased at run time, and a selector that falls through
|
|
60
|
+
* either mislabels the fixture or hands the value to a peer builder that quotes it back.
|
|
61
|
+
*/
|
|
62
|
+
SYNTH_UNSUPPORTED_KIND: "SYNTH_UNSUPPORTED_KIND"
|
|
63
|
+
};
|
|
64
|
+
var SYNTH_FATAL_MESSAGES = Object.freeze({
|
|
65
|
+
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.",
|
|
66
|
+
SYNTH_UNSUPPORTED_QUIRK: "The requested vendor quirk is not in the target format's quirk registry. Compare the request against that format's exported registry (HL7_QUIRKS, CCDA_QUIRKS, ASTM_QUIRKS).",
|
|
67
|
+
SYNTH_QUIRK_ANCHOR_ABSENT: "The quirk transform found no structural anchor to mutate, so the fixture would not carry the deviation it is labelled with. Refusing to emit a mislabeled fixture.",
|
|
68
|
+
SYNTH_INTENDED_WARNING_MISMATCH: "A bare parse of the generated quirk artifact did not produce exactly the declared intended warning code(s). Refusing to emit a mislabeled fixture.",
|
|
69
|
+
SYNTH_UNMAPPED_CODE_SYSTEM: "The concept's code-system URI has no OID mapping in the C-CDA example-code table.",
|
|
70
|
+
SYNTH_INVALID_DECIMAL: "The value could not be read as an X12 decimal.",
|
|
71
|
+
SYNTH_INVALID_RANGE: "An integer range was requested with its maximum below its minimum.",
|
|
72
|
+
SYNTH_EMPTY_POOL: "A value was drawn from an empty pool.",
|
|
73
|
+
SYNTH_INVALID_PROFILE: "defineSynthProfile requires a non-empty string name.",
|
|
74
|
+
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."
|
|
75
|
+
});
|
|
76
|
+
var SynthError = class extends Error {
|
|
77
|
+
/** The stable fatal code. */
|
|
78
|
+
code;
|
|
79
|
+
/**
|
|
80
|
+
* @param code - The stable {@link SynthFatalCode}. The message comes from the frozen registry.
|
|
81
|
+
*/
|
|
82
|
+
constructor(code) {
|
|
83
|
+
super(SYNTH_FATAL_MESSAGES[code]);
|
|
84
|
+
this.name = "SynthError";
|
|
85
|
+
this.code = code;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
32
89
|
// src/rng/rng.ts
|
|
33
90
|
var Sfc32Rng = class {
|
|
34
91
|
seed;
|
|
@@ -46,7 +103,7 @@ var Sfc32Rng = class {
|
|
|
46
103
|
return this.nextUint32() / 4294967296;
|
|
47
104
|
}
|
|
48
105
|
int(min, max) {
|
|
49
|
-
if (max < min) throw new
|
|
106
|
+
if (max < min) throw new SynthError(SYNTH_FATAL_CODES.SYNTH_INVALID_RANGE);
|
|
50
107
|
const span = max - min + 1;
|
|
51
108
|
return min + Math.floor(this.float() * span);
|
|
52
109
|
}
|
|
@@ -54,7 +111,7 @@ var Sfc32Rng = class {
|
|
|
54
111
|
return this.float() < p;
|
|
55
112
|
}
|
|
56
113
|
pick(items) {
|
|
57
|
-
if (items.length === 0) throw new
|
|
114
|
+
if (items.length === 0) throw new SynthError(SYNTH_FATAL_CODES.SYNTH_EMPTY_POOL);
|
|
58
115
|
return items[this.int(0, items.length - 1)];
|
|
59
116
|
}
|
|
60
117
|
digits(n) {
|
|
@@ -582,10 +639,21 @@ function latin1(bytes) {
|
|
|
582
639
|
return out;
|
|
583
640
|
}
|
|
584
641
|
|
|
642
|
+
// src/select.ts
|
|
643
|
+
function resolveKind(allowed, requested) {
|
|
644
|
+
const match = allowed.find((value) => value === requested);
|
|
645
|
+
if (match === void 0) throw new SynthError(SYNTH_FATAL_CODES.SYNTH_UNSUPPORTED_KIND);
|
|
646
|
+
return match;
|
|
647
|
+
}
|
|
648
|
+
function resolveMix(allowed, requested, fallback) {
|
|
649
|
+
if (requested === void 0) return fallback;
|
|
650
|
+
return requested.map((entry) => resolveKind(allowed, entry));
|
|
651
|
+
}
|
|
652
|
+
|
|
585
653
|
// src/profile.ts
|
|
586
654
|
function defineSynthProfile(spec) {
|
|
587
655
|
if (typeof spec.name !== "string" || spec.name.trim().length === 0) {
|
|
588
|
-
throw new
|
|
656
|
+
throw new SynthError(SYNTH_FATAL_CODES.SYNTH_INVALID_PROFILE);
|
|
589
657
|
}
|
|
590
658
|
return Object.freeze({
|
|
591
659
|
name: spec.name,
|
|
@@ -595,28 +663,6 @@ function defineSynthProfile(spec) {
|
|
|
595
663
|
});
|
|
596
664
|
}
|
|
597
665
|
|
|
598
|
-
// src/codes.ts
|
|
599
|
-
var SYNTH_FATAL_CODES = {
|
|
600
|
-
/**
|
|
601
|
-
* A vendor quirk was requested that the target format's profile system does not support. Fatal —
|
|
602
|
-
* never a silent no-op and never a fabricated quirk.
|
|
603
|
-
*/
|
|
604
|
-
SYNTH_UNSUPPORTED_QUIRK: "SYNTH_UNSUPPORTED_QUIRK"
|
|
605
|
-
};
|
|
606
|
-
var SynthError = class extends Error {
|
|
607
|
-
/** The stable fatal code. */
|
|
608
|
-
code;
|
|
609
|
-
/**
|
|
610
|
-
* @param code - The stable {@link SynthFatalCode}.
|
|
611
|
-
* @param message - A human-readable detail (never contains PHI — there is none).
|
|
612
|
-
*/
|
|
613
|
-
constructor(code, message) {
|
|
614
|
-
super(message);
|
|
615
|
-
this.name = "SynthError";
|
|
616
|
-
this.code = code;
|
|
617
|
-
}
|
|
618
|
-
};
|
|
619
|
-
|
|
620
666
|
// src/quirk.ts
|
|
621
667
|
var PROFILE_QUIRK_APPLIED = "PROFILE_QUIRK_APPLIED";
|
|
622
668
|
function sameCodeSet(a, b) {
|
|
@@ -633,12 +679,8 @@ function sameCodeSet(a, b) {
|
|
|
633
679
|
}
|
|
634
680
|
function resolveQuirk(registry, format, name2) {
|
|
635
681
|
const descriptor = registry[name2];
|
|
636
|
-
if (descriptor === void 0) {
|
|
637
|
-
|
|
638
|
-
throw new SynthError(
|
|
639
|
-
SYNTH_FATAL_CODES.SYNTH_UNSUPPORTED_QUIRK,
|
|
640
|
-
`${format}: unsupported quirk "${name2}". The ${format} profile system supports: ${supported}.`
|
|
641
|
-
);
|
|
682
|
+
if (descriptor === void 0 || descriptor.format !== format) {
|
|
683
|
+
throw new SynthError(SYNTH_FATAL_CODES.SYNTH_UNSUPPORTED_QUIRK);
|
|
642
684
|
}
|
|
643
685
|
return descriptor;
|
|
644
686
|
}
|
|
@@ -653,11 +695,9 @@ function profileTolerated(disposition, intendedWarnings, warningsUnderProfile) {
|
|
|
653
695
|
return false;
|
|
654
696
|
}
|
|
655
697
|
}
|
|
656
|
-
function assertIntendedWarnings(
|
|
698
|
+
function assertIntendedWarnings(intendedWarnings, bareWarnings) {
|
|
657
699
|
if (!sameCodeSet(bareWarnings, intendedWarnings)) {
|
|
658
|
-
throw new
|
|
659
|
-
`quirk "${quirk}": the intended-warning contract does not hold \u2014 expected exactly [${intendedWarnings.join(", ")}] but a bare parse produced [${bareWarnings.join(", ")}]. Refusing to emit a mislabeled fixture.`
|
|
660
|
-
);
|
|
700
|
+
throw new SynthError(SYNTH_FATAL_CODES.SYNTH_INTENDED_WARNING_MISMATCH);
|
|
661
701
|
}
|
|
662
702
|
}
|
|
663
703
|
function validateProfileQuirks(profile, registry, format) {
|
|
@@ -666,6 +706,7 @@ function validateProfileQuirks(profile, registry, format) {
|
|
|
666
706
|
}
|
|
667
707
|
|
|
668
708
|
// src/astm/quirk.ts
|
|
709
|
+
var ALL_QUIRK_KINDS = Object.freeze(["Result"]);
|
|
669
710
|
var ASTM_QUIRKS = Object.freeze({
|
|
670
711
|
"unknown-escape": Object.freeze({
|
|
671
712
|
name: "unknown-escape",
|
|
@@ -719,17 +760,14 @@ function applyQuirk(quirk, records) {
|
|
|
719
760
|
}
|
|
720
761
|
function generateAstmQuirk(options) {
|
|
721
762
|
const seed = options.seed ?? 0;
|
|
722
|
-
const kind = "Result";
|
|
763
|
+
const kind = resolveKind(ALL_QUIRK_KINDS, options.kind ?? "Result");
|
|
723
764
|
const descriptor = resolveQuirk(ASTM_QUIRKS, "astm", options.quirk);
|
|
724
765
|
const clean = generateAstmResult({ seed });
|
|
725
766
|
const content = applyQuirk(options.quirk, clean);
|
|
726
767
|
if (content === clean) {
|
|
727
|
-
throw new
|
|
728
|
-
`generateAstmQuirk: quirk "${options.quirk}" found no structural anchor in a ${kind} report at seed ${seed} \u2014 refusing to emit a fixture that does not carry the intended deviation.`
|
|
729
|
-
);
|
|
768
|
+
throw new SynthError(SYNTH_FATAL_CODES.SYNTH_QUIRK_ANCHOR_ABSENT);
|
|
730
769
|
}
|
|
731
770
|
assertIntendedWarnings(
|
|
732
|
-
descriptor.name,
|
|
733
771
|
descriptor.intendedWarnings,
|
|
734
772
|
parseAstmRecords(content).warnings.map((w) => String(w.code))
|
|
735
773
|
);
|
|
@@ -775,6 +813,7 @@ var ALL_ASTM_QUIRKS = Object.freeze(
|
|
|
775
813
|
function astmQuirkCorpus(options) {
|
|
776
814
|
const quirks = options.profile ? validateProfileQuirks(options.profile, ASTM_QUIRKS, "astm") : options.quirks ?? ALL_ASTM_QUIRKS;
|
|
777
815
|
const names = quirks.length > 0 ? quirks : ALL_ASTM_QUIRKS;
|
|
816
|
+
for (const name2 of names) resolveQuirk(ASTM_QUIRKS, "astm", name2);
|
|
778
817
|
const count = options.count ?? names.length;
|
|
779
818
|
const seedStream = createRng(options.seed);
|
|
780
819
|
const artifacts = Array.from({ length: count }, (_unused, i) => {
|
|
@@ -796,7 +835,8 @@ var astmQuirkProfile = defineSynthProfile({
|
|
|
796
835
|
});
|
|
797
836
|
|
|
798
837
|
// src/astm/index.ts
|
|
799
|
-
var
|
|
838
|
+
var ALL_KINDS = Object.freeze(["Result", "Order"]);
|
|
839
|
+
var DEFAULT_MIX = ALL_KINDS;
|
|
800
840
|
function generateKind(kind, seed) {
|
|
801
841
|
switch (kind) {
|
|
802
842
|
case "Result":
|
|
@@ -806,7 +846,8 @@ function generateKind(kind, seed) {
|
|
|
806
846
|
}
|
|
807
847
|
}
|
|
808
848
|
function astmCorpus(options) {
|
|
809
|
-
const { seed
|
|
849
|
+
const { seed } = options;
|
|
850
|
+
const mix = resolveMix(ALL_KINDS, options.mix, DEFAULT_MIX);
|
|
810
851
|
const count = options.count ?? mix.length;
|
|
811
852
|
const seedStream = createRng(seed);
|
|
812
853
|
const artifacts = Array.from({ length: count }, (_unused, i) => {
|