@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
@@ -414,7 +414,8 @@ declare const PROCEDURE_MODIFIERS: readonly string[];
414
414
  declare const PLACES_OF_SERVICE: readonly string[];
415
415
  /**
416
416
  * ICD-10-CM diagnosis codes (HI qualifier `ABK` principal / `ABF` secondary): codes from the TR3
417
- * examples. Structural placeholders only.
417
+ * examples. Structural placeholders only. Each is written without its decimal point (`J209` for
418
+ * J20.9), as the 005010 claim guides transmit a diagnosis code.
418
419
  */
419
420
  declare const DIAGNOSES: readonly X12ExampleCode[];
420
421
  /** NUBC revenue codes (837I SV2-01): spec-example codes. */
@@ -465,6 +466,12 @@ interface X12CorpusOptions {
465
466
  readonly count?: number;
466
467
  /** The transaction kinds to cycle through. Defaults to one of each. */
467
468
  readonly mix?: readonly X12CorpusKind[];
469
+ /**
470
+ * Whether each artifact is read back through its parser and the parser's findings recorded as its
471
+ * `warnings`. Defaults to `true`. `false` skips the read, a large share of a corpus's time; every
472
+ * artifact's `warnings` is then empty without having been checked.
473
+ */
474
+ readonly verify?: boolean;
468
475
  }
469
476
  /**
470
477
  * Build a reproducible {@link Corpus} of spec-clean X12 transactions. Each transaction is generated from
@@ -414,7 +414,8 @@ declare const PROCEDURE_MODIFIERS: readonly string[];
414
414
  declare const PLACES_OF_SERVICE: readonly string[];
415
415
  /**
416
416
  * ICD-10-CM diagnosis codes (HI qualifier `ABK` principal / `ABF` secondary): codes from the TR3
417
- * examples. Structural placeholders only.
417
+ * examples. Structural placeholders only. Each is written without its decimal point (`J209` for
418
+ * J20.9), as the 005010 claim guides transmit a diagnosis code.
418
419
  */
419
420
  declare const DIAGNOSES: readonly X12ExampleCode[];
420
421
  /** NUBC revenue codes (837I SV2-01): spec-example codes. */
@@ -465,6 +466,12 @@ interface X12CorpusOptions {
465
466
  readonly count?: number;
466
467
  /** The transaction kinds to cycle through. Defaults to one of each. */
467
468
  readonly mix?: readonly X12CorpusKind[];
469
+ /**
470
+ * Whether each artifact is read back through its parser and the parser's findings recorded as its
471
+ * `warnings`. Defaults to `true`. `false` skips the read, a large share of a corpus's time; every
472
+ * artifact's `warnings` is then empty without having been checked.
473
+ */
474
+ readonly verify?: boolean;
468
475
  }
469
476
  /**
470
477
  * Build a reproducible {@link Corpus} of spec-clean X12 transactions. Each transaction is generated from
@@ -1,4 +1,12 @@
1
- import { X12Decimal, build837D, build837I, build837P, build835, build271, serializeX12, parseX12 } from '@cosyte/x12';
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();
@@ -167,8 +176,32 @@ function makeCorpus(seed, artifacts, quirks = []) {
167
176
  artifacts: Object.freeze(frozenArtifacts)
168
177
  });
169
178
  }
179
+ function defaultHost() {
180
+ if (typeof import.meta.resolve !== "function") return { require: __require, resolve: void 0 };
181
+ return { require: createRequire(import.meta.url), resolve: (s) => import.meta.resolve(s) };
182
+ }
183
+ function isRequireEsmRefusal(error) {
184
+ return error?.code === "ERR_REQUIRE_ESM";
185
+ }
186
+ function loadPeer(specifier, host) {
187
+ if (host.resolve === void 0) return host.require(specifier);
188
+ const entry = fileURLToPath(host.resolve(specifier));
189
+ try {
190
+ return host.require(entry);
191
+ } catch (error) {
192
+ if (!isRequireEsmRefusal(error)) throw error;
193
+ return host.require(specifier);
194
+ }
195
+ }
196
+ function lazyPeer(specifier, host) {
197
+ let loaded;
198
+ return () => loaded ??= loadPeer(specifier, defaultHost());
199
+ }
200
+ var x12Peer = lazyPeer("@cosyte/x12");
201
+
202
+ // src/x12/money.ts
170
203
  function dec(value) {
171
- const d = X12Decimal.fromString(value);
204
+ const d = x12Peer().X12Decimal.fromString(value);
172
205
  if (d === void 0) throw new SynthError(SYNTH_FATAL_CODES.SYNTH_INVALID_DECIMAL);
173
206
  return d;
174
207
  }
@@ -535,12 +568,12 @@ var PROCEDURE_MODIFIERS = Object.freeze(["25", "59", "76", "GT"]);
535
568
  var PLACES_OF_SERVICE = Object.freeze(["11", "22", "21", "12", "49"]);
536
569
  var DIAGNOSES = Object.freeze(
537
570
  [
538
- { code: "J20.9", label: "acute bronchitis, unspecified" },
539
- { code: "E11.9", label: "type 2 diabetes mellitus without complications" },
571
+ { code: "J209", label: "acute bronchitis, unspecified" },
572
+ { code: "E119", label: "type 2 diabetes mellitus without complications" },
540
573
  { code: "I10", label: "essential (primary) hypertension" },
541
- { code: "M54.5", label: "low back pain" },
542
- { code: "R07.9", label: "chest pain, unspecified" },
543
- { code: "Z00.00", label: "general adult medical exam without abnormal findings" }
574
+ { code: "M545", label: "low back pain" },
575
+ { code: "R079", label: "chest pain, unspecified" },
576
+ { code: "Z0000", label: "general adult medical exam without abnormal findings" }
544
577
  ].map((entry) => Object.freeze(entry))
545
578
  );
546
579
  var REVENUE_CODES = Object.freeze(
@@ -769,11 +802,11 @@ function generate837(variant, options) {
769
802
  const spec = specOf(rng, resolved);
770
803
  switch (resolved) {
771
804
  case "P":
772
- return build837P(spec);
805
+ return x12Peer().build837P(spec);
773
806
  case "I":
774
- return build837I(spec);
807
+ return x12Peer().build837I(spec);
775
808
  case "D":
776
- return build837D(spec);
809
+ return x12Peer().build837D(spec);
777
810
  }
778
811
  }
779
812
  function generate837P(options) {
@@ -785,6 +818,8 @@ function generate837I(options) {
785
818
  function generate837D(options) {
786
819
  return generate837("D", options);
787
820
  }
821
+
822
+ // src/x12/remit-835.ts
788
823
  function generate835(options) {
789
824
  const rng = createRng(options.seed);
790
825
  const partners = x12TradingPartners(rng);
@@ -885,8 +920,10 @@ function generate835(options) {
885
920
  },
886
921
  claims: [claim]
887
922
  };
888
- return build835(spec);
923
+ return x12Peer().build835(spec);
889
924
  }
925
+
926
+ // src/x12/eligibility-271.ts
890
927
  function generate271(options) {
891
928
  const rng = createRng(options.seed);
892
929
  const partners = x12TradingPartners(rng);
@@ -956,7 +993,8 @@ function generate271(options) {
956
993
  serviceTypeCodes: serviceTypes,
957
994
  inPlanNetwork: "Y",
958
995
  monetaryAmount: dec(money(rng.int(500, 5e3))),
959
- percent: dec(String(rng.pick([80, 90, 100])))
996
+ percent: dec(rng.pick([".8", ".9", "1"]))
997
+ // EB-08 is a decimal fraction
960
998
  }
961
999
  ]
962
1000
  }
@@ -966,13 +1004,15 @@ function generate271(options) {
966
1004
  }
967
1005
  ]
968
1006
  };
969
- return build271(spec);
1007
+ return x12Peer().build271(spec);
970
1008
  }
1009
+
1010
+ // src/x12/round-trip.ts
971
1011
  function roundTrip(interchange) {
972
- const content = serializeX12(interchange);
973
- const reparsed = parseX12(content);
1012
+ const content = x12Peer().serializeX12(interchange);
1013
+ const reparsed = x12Peer().parseX12(content);
974
1014
  const warnings = reparsed.warnings.map((w) => String(w.code));
975
- const byteStable = serializeX12(reparsed) === content;
1015
+ const byteStable = x12Peer().serializeX12(reparsed) === content;
976
1016
  return {
977
1017
  content,
978
1018
  warnings,
@@ -980,6 +1020,14 @@ function roundTrip(interchange) {
980
1020
  specClean: warnings.length === 0 && byteStable
981
1021
  };
982
1022
  }
1023
+ function x12CorpusArtifact(interchange, verify) {
1024
+ const content = x12Peer().serializeX12(interchange);
1025
+ if (!verify) return { content, warnings: UNCHECKED };
1026
+ return {
1027
+ content,
1028
+ warnings: x12Peer().parseX12(content).warnings.map((w) => String(w.code))
1029
+ };
1030
+ }
983
1031
 
984
1032
  // src/x12/index.ts
985
1033
  var ALL_KINDS = Object.freeze(["837P", "837I", "837D", "835", "271"]);
@@ -987,26 +1035,26 @@ var DEFAULT_MIX = ALL_KINDS;
987
1035
  function generateKind(kind, seed) {
988
1036
  switch (kind) {
989
1037
  case "835":
990
- return roundTrip(generate835({ seed }));
1038
+ return generate835({ seed });
991
1039
  case "271":
992
- return roundTrip(generate271({ seed }));
1040
+ return generate271({ seed });
993
1041
  case "837P":
994
- return roundTrip(generate837("P", { seed }));
1042
+ return generate837("P", { seed });
995
1043
  case "837I":
996
- return roundTrip(generate837("I", { seed }));
1044
+ return generate837("I", { seed });
997
1045
  case "837D":
998
- return roundTrip(generate837("D", { seed }));
1046
+ return generate837("D", { seed });
999
1047
  }
1000
1048
  }
1001
1049
  function x12Corpus(options) {
1002
- const { seed } = options;
1050
+ const { seed, verify = true } = options;
1003
1051
  const mix = resolveMix(ALL_KINDS, options.mix, DEFAULT_MIX);
1004
1052
  const count = options.count ?? mix.length;
1005
1053
  const seedStream = createRng(seed);
1006
1054
  const artifacts = Array.from({ length: count }, (_unused, i) => {
1007
1055
  const kind = mix[i % mix.length] ?? "837P";
1008
1056
  const txSeed = seedStream.nextUint32();
1009
- const rt = generateKind(kind, txSeed);
1057
+ const rt = x12CorpusArtifact(generateKind(kind, txSeed), verify);
1010
1058
  return {
1011
1059
  format: "x12",
1012
1060
  kind,