@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/fhir/index.cjs
CHANGED
|
@@ -33,6 +33,45 @@ function sfc32Next(s) {
|
|
|
33
33
|
return t >>> 0;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
// src/codes.ts
|
|
37
|
+
var SYNTH_FATAL_CODES = {
|
|
38
|
+
/** An integer range was requested with its maximum below its minimum. Fatal. */
|
|
39
|
+
SYNTH_INVALID_RANGE: "SYNTH_INVALID_RANGE",
|
|
40
|
+
/** A value was drawn from an empty pool. Fatal — never a fabricated substitute. */
|
|
41
|
+
SYNTH_EMPTY_POOL: "SYNTH_EMPTY_POOL",
|
|
42
|
+
/**
|
|
43
|
+
* A caller-supplied selector (a message kind, a document type, a corpus mix entry, a claim
|
|
44
|
+
* variant, a Bundle type, a resource profile) is not in the closed set that governs it. Fatal —
|
|
45
|
+
* see `resolveKind`: a selector union is erased at run time, and a selector that falls through
|
|
46
|
+
* either mislabels the fixture or hands the value to a peer builder that quotes it back.
|
|
47
|
+
*/
|
|
48
|
+
SYNTH_UNSUPPORTED_KIND: "SYNTH_UNSUPPORTED_KIND"
|
|
49
|
+
};
|
|
50
|
+
var SYNTH_FATAL_MESSAGES = Object.freeze({
|
|
51
|
+
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.",
|
|
52
|
+
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).",
|
|
53
|
+
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.",
|
|
54
|
+
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.",
|
|
55
|
+
SYNTH_UNMAPPED_CODE_SYSTEM: "The concept's code-system URI has no OID mapping in the C-CDA example-code table.",
|
|
56
|
+
SYNTH_INVALID_DECIMAL: "The value could not be read as an X12 decimal.",
|
|
57
|
+
SYNTH_INVALID_RANGE: "An integer range was requested with its maximum below its minimum.",
|
|
58
|
+
SYNTH_EMPTY_POOL: "A value was drawn from an empty pool.",
|
|
59
|
+
SYNTH_INVALID_PROFILE: "defineSynthProfile requires a non-empty string name.",
|
|
60
|
+
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."
|
|
61
|
+
});
|
|
62
|
+
var SynthError = class extends Error {
|
|
63
|
+
/** The stable fatal code. */
|
|
64
|
+
code;
|
|
65
|
+
/**
|
|
66
|
+
* @param code - The stable {@link SynthFatalCode}. The message comes from the frozen registry.
|
|
67
|
+
*/
|
|
68
|
+
constructor(code) {
|
|
69
|
+
super(SYNTH_FATAL_MESSAGES[code]);
|
|
70
|
+
this.name = "SynthError";
|
|
71
|
+
this.code = code;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
36
75
|
// src/rng/rng.ts
|
|
37
76
|
var Sfc32Rng = class {
|
|
38
77
|
seed;
|
|
@@ -50,7 +89,7 @@ var Sfc32Rng = class {
|
|
|
50
89
|
return this.nextUint32() / 4294967296;
|
|
51
90
|
}
|
|
52
91
|
int(min, max) {
|
|
53
|
-
if (max < min) throw new
|
|
92
|
+
if (max < min) throw new SynthError(SYNTH_FATAL_CODES.SYNTH_INVALID_RANGE);
|
|
54
93
|
const span = max - min + 1;
|
|
55
94
|
return min + Math.floor(this.float() * span);
|
|
56
95
|
}
|
|
@@ -58,7 +97,7 @@ var Sfc32Rng = class {
|
|
|
58
97
|
return this.float() < p;
|
|
59
98
|
}
|
|
60
99
|
pick(items) {
|
|
61
|
-
if (items.length === 0) throw new
|
|
100
|
+
if (items.length === 0) throw new SynthError(SYNTH_FATAL_CODES.SYNTH_EMPTY_POOL);
|
|
62
101
|
return items[this.int(0, items.length - 1)];
|
|
63
102
|
}
|
|
64
103
|
digits(n) {
|
|
@@ -743,7 +782,19 @@ var EXAMPLE_ENCOUNTER_CLASSES = Object.freeze([
|
|
|
743
782
|
Object.freeze({ system: SYSTEM.V3_ACT_CODE, code: "IMP", display: "inpatient encounter" })
|
|
744
783
|
]);
|
|
745
784
|
|
|
785
|
+
// src/select.ts
|
|
786
|
+
function resolveKind(allowed, requested) {
|
|
787
|
+
const match = allowed.find((value) => value === requested);
|
|
788
|
+
if (match === void 0) throw new SynthError(SYNTH_FATAL_CODES.SYNTH_UNSUPPORTED_KIND);
|
|
789
|
+
return match;
|
|
790
|
+
}
|
|
791
|
+
function resolveMix(allowed, requested, fallback) {
|
|
792
|
+
if (requested === void 0) return fallback;
|
|
793
|
+
return requested.map((entry) => resolveKind(allowed, entry));
|
|
794
|
+
}
|
|
795
|
+
|
|
746
796
|
// src/fhir/patient.ts
|
|
797
|
+
var PATIENT_PROFILES = Object.freeze(["base", "us-core"]);
|
|
747
798
|
function ombExtension(url, category) {
|
|
748
799
|
return fhir.complex([
|
|
749
800
|
prop("url", str(url)),
|
|
@@ -757,7 +808,8 @@ function ombExtension(url, category) {
|
|
|
757
808
|
]);
|
|
758
809
|
}
|
|
759
810
|
function generatePatient(options = {}) {
|
|
760
|
-
const { seed = 0
|
|
811
|
+
const { seed = 0 } = options;
|
|
812
|
+
const profile = resolveKind(PATIENT_PROFILES, options.profile ?? "base");
|
|
761
813
|
const rng = createRng(seed);
|
|
762
814
|
const id = fhirPatientIdentity(rng);
|
|
763
815
|
const usCore = profile === "us-core";
|
|
@@ -1174,6 +1226,11 @@ function roundTrip(resource, options = {}) {
|
|
|
1174
1226
|
}
|
|
1175
1227
|
|
|
1176
1228
|
// src/fhir/bundle.ts
|
|
1229
|
+
var BUNDLE_TYPES = Object.freeze([
|
|
1230
|
+
"collection",
|
|
1231
|
+
"transaction",
|
|
1232
|
+
"document"
|
|
1233
|
+
]);
|
|
1177
1234
|
function resourceTypeOf(resource) {
|
|
1178
1235
|
const rt = resource.properties.find((p) => p.name === "resourceType");
|
|
1179
1236
|
return rt !== void 0 && rt.value.kind === "primitive" ? String(rt.value.value) : "Resource";
|
|
@@ -1275,7 +1332,8 @@ function documentSections(urls) {
|
|
|
1275
1332
|
];
|
|
1276
1333
|
}
|
|
1277
1334
|
function generateBundle(options = {}) {
|
|
1278
|
-
const { seed = 0
|
|
1335
|
+
const { seed = 0 } = options;
|
|
1336
|
+
const type = resolveKind(BUNDLE_TYPES, options.type ?? "collection");
|
|
1279
1337
|
const rng = createRng(seed);
|
|
1280
1338
|
const spine = buildSpine(rng);
|
|
1281
1339
|
const members = type === "document" ? [
|
|
@@ -1326,6 +1384,21 @@ function generateBundle(options = {}) {
|
|
|
1326
1384
|
props.push(prop("entry", fhir.list(entries)));
|
|
1327
1385
|
return fhir.complex(props);
|
|
1328
1386
|
}
|
|
1387
|
+
var ALL_KINDS = Object.freeze([
|
|
1388
|
+
"Patient",
|
|
1389
|
+
"USCorePatient",
|
|
1390
|
+
"Condition",
|
|
1391
|
+
"ObservationLab",
|
|
1392
|
+
"VitalSign",
|
|
1393
|
+
"MedicationRequest",
|
|
1394
|
+
"Encounter",
|
|
1395
|
+
"Immunization",
|
|
1396
|
+
"AllergyIntolerance",
|
|
1397
|
+
"Procedure",
|
|
1398
|
+
"DiagnosticReport",
|
|
1399
|
+
"Bundle",
|
|
1400
|
+
"DocumentBundle"
|
|
1401
|
+
]);
|
|
1329
1402
|
var DEFAULT_MIX = Object.freeze([
|
|
1330
1403
|
"USCorePatient",
|
|
1331
1404
|
"Condition",
|
|
@@ -1371,7 +1444,7 @@ function generateKind(kind, seed) {
|
|
|
1371
1444
|
}
|
|
1372
1445
|
function fhirCorpus(options) {
|
|
1373
1446
|
const { seed, count = 1 } = options;
|
|
1374
|
-
const kinds = options.mix
|
|
1447
|
+
const kinds = resolveMix(ALL_KINDS, options.mix, DEFAULT_MIX);
|
|
1375
1448
|
const seedStream = createRng(seed);
|
|
1376
1449
|
const artifacts = Array.from({ length: count }, (_unused, i) => {
|
|
1377
1450
|
const kind = kinds[i % kinds.length] ?? "USCorePatient";
|