@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
@@ -91,6 +91,7 @@ declare function generateAstmResultFramed(options: GenerateAstmOptions): Uint8Ar
91
91
  *
92
92
  * @module
93
93
  */
94
+
94
95
  /** The verdict of one round-trip through `@cosyte/astm`. */
95
96
  interface AstmRoundTripResult {
96
97
  /** The serialized ASTM wire text (records: the `CR`-terminated stream; framed: the raw bytes as latin1). */
@@ -398,6 +399,12 @@ interface AstmCorpusOptions {
398
399
  readonly count?: number;
399
400
  /** The message kinds to cycle through. Defaults to one of each. */
400
401
  readonly mix?: readonly AstmCorpusKind[];
402
+ /**
403
+ * Whether each artifact is read back through its parser and the parser's findings recorded as its
404
+ * `warnings`. Defaults to `true`. `false` skips the read, a large share of a corpus's time; every
405
+ * artifact's `warnings` is then empty without having been checked.
406
+ */
407
+ readonly verify?: boolean;
401
408
  }
402
409
  /**
403
410
  * Build a reproducible {@link Corpus} of spec-clean ASTM messages. Each message is generated from a
@@ -91,6 +91,7 @@ declare function generateAstmResultFramed(options: GenerateAstmOptions): Uint8Ar
91
91
  *
92
92
  * @module
93
93
  */
94
+
94
95
  /** The verdict of one round-trip through `@cosyte/astm`. */
95
96
  interface AstmRoundTripResult {
96
97
  /** The serialized ASTM wire text (records: the `CR`-terminated stream; framed: the raw bytes as latin1). */
@@ -398,6 +399,12 @@ interface AstmCorpusOptions {
398
399
  readonly count?: number;
399
400
  /** The message kinds to cycle through. Defaults to one of each. */
400
401
  readonly mix?: readonly AstmCorpusKind[];
402
+ /**
403
+ * Whether each artifact is read back through its parser and the parser's findings recorded as its
404
+ * `warnings`. Defaults to `true`. `false` skips the read, a large share of a corpus's time; every
405
+ * artifact's `warnings` is then empty without having been checked.
406
+ */
407
+ readonly verify?: boolean;
401
408
  }
402
409
  /**
403
410
  * Build a reproducible {@link Corpus} of spec-clean ASTM messages. Each message is generated from a
@@ -1,4 +1,12 @@
1
- import { buildAstmMessage, composeAstmFrames, parseAstmRecords, serializeAstmRecords, parseFramedAstm, serializeFramedAstm, astmProfiles } from '@cosyte/astm';
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
+ });
2
10
 
3
11
  // src/rng/splitmix32.ts
4
12
  function splitmix32(seed) {
@@ -148,6 +156,7 @@ function createRng(seed) {
148
156
  }
149
157
 
150
158
  // src/corpus.ts
159
+ var UNCHECKED = Object.freeze([]);
151
160
  function makeCorpus(seed, artifacts, quirks = []) {
152
161
  const counts = {};
153
162
  const formats = /* @__PURE__ */ new Set();
@@ -584,6 +593,28 @@ var ASTM_COMMENT_TEXT = Object.freeze([
584
593
  "Sample generated by @cosyte/synth.",
585
594
  "Placeholder result comment for conformance testing."
586
595
  ]);
596
+ function defaultHost() {
597
+ if (typeof import.meta.resolve !== "function") return { require: __require, resolve: void 0 };
598
+ return { require: createRequire(import.meta.url), resolve: (s) => import.meta.resolve(s) };
599
+ }
600
+ function isRequireEsmRefusal(error) {
601
+ return error?.code === "ERR_REQUIRE_ESM";
602
+ }
603
+ function loadPeer(specifier, host) {
604
+ if (host.resolve === void 0) return host.require(specifier);
605
+ const entry = fileURLToPath(host.resolve(specifier));
606
+ try {
607
+ return host.require(entry);
608
+ } catch (error) {
609
+ if (!isRequireEsmRefusal(error)) throw error;
610
+ return host.require(specifier);
611
+ }
612
+ }
613
+ function lazyPeer(specifier, host) {
614
+ let loaded;
615
+ return () => loaded ??= loadPeer(specifier, defaultHost());
616
+ }
617
+ var astmPeer = lazyPeer("@cosyte/astm");
587
618
 
588
619
  // src/astm/message.ts
589
620
  function resultValue(rng, low, high, decimals) {
@@ -632,13 +663,14 @@ function buildResultInput(options) {
632
663
  records.push({ type: "C", source: "L", text: rng.pick(ASTM_COMMENT_TEXT), commentType: "G" });
633
664
  }
634
665
  return {
635
- header: { fields: [head.sender, head.analyzer] },
666
+ // H.3 (message control id) and H.4 (access password) stay empty; H.5 is the sender name.
667
+ header: { fields: ["", "", head.sender] },
636
668
  records,
637
669
  terminationCode: "N"
638
670
  };
639
671
  }
640
672
  function generateAstmResult(options) {
641
- return buildAstmMessage(buildResultInput(options));
673
+ return astmPeer().buildAstmMessage(buildResultInput(options));
642
674
  }
643
675
  function generateAstmOrder(options) {
644
676
  return generateAstmResult({ ...options, resultCount: 0, comment: false });
@@ -646,21 +678,23 @@ function generateAstmOrder(options) {
646
678
  function generateAstmResultFramed(options) {
647
679
  const raw = generateAstmResult(options);
648
680
  const recordLines = raw.split("\r").filter((line) => line.length > 0).map((line) => `${line}\r`);
649
- return composeAstmFrames(recordLines);
681
+ return astmPeer().composeAstmFrames(recordLines);
650
682
  }
683
+
684
+ // src/astm/round-trip.ts
651
685
  function astmRoundTrip(raw) {
652
- const message = parseAstmRecords(raw);
686
+ const message = astmPeer().parseAstmRecords(raw);
653
687
  const warnings = message.warnings.map((w) => String(w.code));
654
- const byteStable = serializeAstmRecords(message) === raw;
688
+ const byteStable = astmPeer().serializeAstmRecords(message) === raw;
655
689
  return { content: raw, warnings, byteStable, specClean: warnings.length === 0 && byteStable };
656
690
  }
657
691
  function astmFramedRoundTrip(bytes) {
658
- const { message, frameWarnings } = parseFramedAstm(bytes);
692
+ const { message, frameWarnings } = astmPeer().parseFramedAstm(bytes);
659
693
  const warnings = [
660
694
  ...frameWarnings.map((w) => String(w.code)),
661
695
  ...message.warnings.map((w) => String(w.code))
662
696
  ];
663
- const reframed = serializeFramedAstm(message);
697
+ const reframed = astmPeer().serializeFramedAstm(message);
664
698
  const byteStable = bytesEqual(reframed, bytes);
665
699
  const content = latin1(bytes);
666
700
  return { content, warnings, byteStable, specClean: warnings.length === 0 && byteStable };
@@ -675,6 +709,11 @@ function latin1(bytes) {
675
709
  for (const b of bytes) out += String.fromCharCode(b);
676
710
  return out;
677
711
  }
712
+ function astmCorpusArtifact(raw, verify) {
713
+ if (!verify) return { content: raw, warnings: UNCHECKED };
714
+ const warnings = astmPeer().parseAstmRecords(raw).warnings.map((w) => String(w.code));
715
+ return { content: raw, warnings };
716
+ }
678
717
 
679
718
  // src/select.ts
680
719
  function resolveKind(allowed, requested) {
@@ -762,7 +801,7 @@ var ASTM_QUIRKS = Object.freeze({
762
801
  })
763
802
  });
764
803
  function toleratingProfile(quirk) {
765
- return quirk === "unknown-escape" ? astmProfiles.referenceCorpus : void 0;
804
+ return quirk === "unknown-escape" ? astmPeer().astmProfiles.referenceCorpus : void 0;
766
805
  }
767
806
  var CR = "\r";
768
807
  function applyQuirk(quirk, records) {
@@ -806,7 +845,7 @@ function generateAstmQuirk(options) {
806
845
  }
807
846
  assertIntendedWarnings(
808
847
  descriptor.intendedWarnings,
809
- parseAstmRecords(content).warnings.map((w) => String(w.code))
848
+ astmPeer().parseAstmRecords(content).warnings.map((w) => String(w.code))
810
849
  );
811
850
  return Object.freeze({
812
851
  format: "astm",
@@ -819,12 +858,10 @@ function generateAstmQuirk(options) {
819
858
  function astmQuirkRoundTrip(artifact) {
820
859
  const quirk = artifact.quirk;
821
860
  const descriptor = resolveQuirk(ASTM_QUIRKS, "astm", quirk);
822
- const bare = parseAstmRecords(artifact.content).warnings.map((w) => String(w.code));
861
+ const bare = astmPeer().parseAstmRecords(artifact.content).warnings.map((w) => String(w.code));
823
862
  const profile = toleratingProfile(quirk);
824
863
  const withProfile = profile !== void 0 && descriptor.toleratingProfile !== void 0 ? (() => {
825
- const warnings = parseAstmRecords(artifact.content, { profile }).warnings.map(
826
- (w) => String(w.code)
827
- );
864
+ const warnings = astmPeer().parseAstmRecords(artifact.content, { profile }).warnings.map((w) => String(w.code));
828
865
  return {
829
866
  profileName: descriptor.toleratingProfile,
830
867
  disposition: descriptor.disposition,
@@ -874,23 +911,23 @@ var astmQuirkProfile = defineSynthProfile({
874
911
  // src/astm/index.ts
875
912
  var ALL_KINDS = Object.freeze(["Result", "Order"]);
876
913
  var DEFAULT_MIX = ALL_KINDS;
877
- function generateKind(kind, seed) {
914
+ function generateKind(kind, seed, verify) {
878
915
  switch (kind) {
879
916
  case "Result":
880
- return astmRoundTrip(generateAstmResult({ seed }));
917
+ return astmCorpusArtifact(generateAstmResult({ seed }), verify);
881
918
  case "Order":
882
- return astmRoundTrip(generateAstmOrder({ seed }));
919
+ return astmCorpusArtifact(generateAstmOrder({ seed }), verify);
883
920
  }
884
921
  }
885
922
  function astmCorpus(options) {
886
- const { seed } = options;
923
+ const { seed, verify = true } = options;
887
924
  const mix = resolveMix(ALL_KINDS, options.mix, DEFAULT_MIX);
888
925
  const count = options.count ?? mix.length;
889
926
  const seedStream = createRng(seed);
890
927
  const artifacts = Array.from({ length: count }, (_unused, i) => {
891
928
  const kind = mix[i % mix.length] ?? "Result";
892
929
  const msgSeed = seedStream.nextUint32();
893
- const rt = generateKind(kind, msgSeed);
930
+ const rt = generateKind(kind, msgSeed, verify);
894
931
  return {
895
932
  format: "astm",
896
933
  kind,