@cosyte/synth 0.0.9 → 0.1.1

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 (55) hide show
  1. package/CHANGELOG.md +83 -2
  2. package/README.md +40 -31
  3. package/dist/astm/index.cjs +18 -6
  4. package/dist/astm/index.cjs.map +1 -1
  5. package/dist/astm/index.d.cts +6 -6
  6. package/dist/astm/index.d.ts +6 -6
  7. package/dist/astm/index.mjs +18 -6
  8. package/dist/astm/index.mjs.map +1 -1
  9. package/dist/ccda/index.cjs +23 -7
  10. package/dist/ccda/index.cjs.map +1 -1
  11. package/dist/ccda/index.d.cts +2 -2
  12. package/dist/ccda/index.d.ts +2 -2
  13. package/dist/ccda/index.mjs +23 -7
  14. package/dist/ccda/index.mjs.map +1 -1
  15. package/dist/deid/index.cjs +26 -8
  16. package/dist/deid/index.cjs.map +1 -1
  17. package/dist/deid/index.d.cts +3 -3
  18. package/dist/deid/index.d.ts +3 -3
  19. package/dist/deid/index.mjs +26 -8
  20. package/dist/deid/index.mjs.map +1 -1
  21. package/dist/fhir/index.cjs +174 -7
  22. package/dist/fhir/index.cjs.map +1 -1
  23. package/dist/fhir/index.d.cts +163 -2
  24. package/dist/fhir/index.d.ts +163 -2
  25. package/dist/fhir/index.mjs +171 -9
  26. package/dist/fhir/index.mjs.map +1 -1
  27. package/dist/hl7/index.cjs +18 -6
  28. package/dist/hl7/index.cjs.map +1 -1
  29. package/dist/hl7/index.d.cts +3 -3
  30. package/dist/hl7/index.d.ts +3 -3
  31. package/dist/hl7/index.mjs +18 -6
  32. package/dist/hl7/index.mjs.map +1 -1
  33. package/dist/index.cjs +37 -6
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +174 -40
  36. package/dist/index.d.ts +174 -40
  37. package/dist/index.mjs +36 -7
  38. package/dist/index.mjs.map +1 -1
  39. package/dist/ncpdp/index.cjs +18 -6
  40. package/dist/ncpdp/index.cjs.map +1 -1
  41. package/dist/ncpdp/index.d.cts +2 -2
  42. package/dist/ncpdp/index.d.ts +2 -2
  43. package/dist/ncpdp/index.mjs +18 -6
  44. package/dist/ncpdp/index.mjs.map +1 -1
  45. package/dist/{providers-B9uVinAe.d.cts → providers-DcPrqmp5.d.cts} +20 -6
  46. package/dist/{providers-B9uVinAe.d.ts → providers-DcPrqmp5.d.ts} +20 -6
  47. package/dist/{quirk-IaHp4z7N.d.cts → quirk-CilFUhwX.d.cts} +1 -1
  48. package/dist/{quirk-HZdznAkM.d.ts → quirk-DmqYw3Vk.d.ts} +1 -1
  49. package/dist/x12/index.cjs +18 -6
  50. package/dist/x12/index.cjs.map +1 -1
  51. package/dist/x12/index.d.cts +3 -3
  52. package/dist/x12/index.d.ts +3 -3
  53. package/dist/x12/index.mjs +18 -6
  54. package/dist/x12/index.mjs.map +1 -1
  55. package/package.json +24 -10
@@ -1,5 +1,5 @@
1
- import { S as SyntheticName, R as Rng, C as Corpus } from '../providers-B9uVinAe.cjs';
2
- import { Q as QuirkDescriptor, S as SynthProfile, a as QuirkArtifact, b as QuirkRoundTripResult } from '../quirk-IaHp4z7N.cjs';
1
+ import { S as SyntheticName, R as Rng, C as Corpus } from '../providers-DcPrqmp5.cjs';
2
+ import { Q as QuirkDescriptor, S as SynthProfile, a as QuirkArtifact, b as QuirkRoundTripResult } from '../quirk-CilFUhwX.cjs';
3
3
 
4
4
  /**
5
5
  * Spec-clean ASTM (E1394 / CLSI LIS02) message generation: the `H`/`P`/`O`/`R`/`C`/`L` record report,
@@ -10,7 +10,7 @@ import { Q as QuirkDescriptor, S as SynthProfile, a as QuirkArtifact, b as Quirk
10
10
  *
11
11
  * A framed **E1381 / CLSI LIS01** variant is also offered ({@link generateAstmResultFramed}) via
12
12
  * `composeAstmFrames`, which frames each record into `<STX> FN text <ETB|ETX> CS <CR><LF>` with the
13
- * **modulo-256 checksum and the `0`–`7` frame number computed by the parser**, never faked. Both round
13
+ * **modulo-256 checksum and the `0` to `7` frame number computed by the parser**, never faked. Both round
14
14
  * trip through `@cosyte/astm` cleanly (`parseAstmRecords` / `parseFramedAstm`: see `./round-trip`).
15
15
  *
16
16
  * Every value at a PHI-bearing locus (the `P` record's name / DOB / practice+lab IDs) is
@@ -24,7 +24,7 @@ import { Q as QuirkDescriptor, S as SynthProfile, a as QuirkArtifact, b as Quirk
24
24
  interface GenerateAstmOptions {
25
25
  /** The seed (deterministic: same seed yields a byte-identical message). */
26
26
  readonly seed: number;
27
- /** How many `R` (result) records to emit. Defaults to a seeded 1–4. */
27
+ /** How many `R` (result) records to emit. Defaults to a seeded 1 to 4. */
28
28
  readonly resultCount?: number;
29
29
  /** Whether to append a `C` (comment) record after the results. Defaults to `true`. */
30
30
  readonly comment?: boolean;
@@ -61,7 +61,7 @@ declare function generateAstmOrder(options: GenerateAstmOptions): string;
61
61
  /**
62
62
  * Generate a spec-clean **framed** ASTM result message: the same `H`/`P`/`O`/`R`…/`C`/`L` records,
63
63
  * wrapped in the **E1381 / CLSI LIS01** frame envelope (`<STX> FN text <ETB|ETX> CS <CR><LF>`) via
64
- * `@cosyte/astm`'s `composeAstmFrames`. The **modulo-256 checksum and the `0`–`7` frame number are
64
+ * `@cosyte/astm`'s `composeAstmFrames`. The **modulo-256 checksum and the `0` to `7` frame number are
65
65
  * computed by the parser** (never hand-written), and a record over 240 bytes is split across frames,
66
66
  * so the bytes round-trip through `parseFramedAstm` with zero frame **and** record warnings (see
67
67
  * `./round-trip`). Each record is framed independently (one `ETX`-closed run per record), mirroring what
@@ -382,7 +382,7 @@ declare const astmQuirkProfile: SynthProfile;
382
382
  * synthetic-by-construction. The practice- and laboratory-assigned patient IDs are
383
383
  * minted independently, so they stay **distinct**.
384
384
  * - **Framing (E1381):** `generateAstmResultFramed` via `composeAstmFrames`, the modulo-256 checksum
385
- * and the `0`–`7` frame number are **computed by the parser, never faked**, and the bytes round-trip
385
+ * and the `0` to `7` frame number are **computed by the parser, never faked**, and the bytes round-trip
386
386
  * through `parseFramedAstm` with zero frame **and** record warnings.
387
387
  *
388
388
  * @module
@@ -1,5 +1,5 @@
1
- import { S as SyntheticName, R as Rng, C as Corpus } from '../providers-B9uVinAe.js';
2
- import { Q as QuirkDescriptor, S as SynthProfile, a as QuirkArtifact, b as QuirkRoundTripResult } from '../quirk-HZdznAkM.js';
1
+ import { S as SyntheticName, R as Rng, C as Corpus } from '../providers-DcPrqmp5.js';
2
+ import { Q as QuirkDescriptor, S as SynthProfile, a as QuirkArtifact, b as QuirkRoundTripResult } from '../quirk-DmqYw3Vk.js';
3
3
 
4
4
  /**
5
5
  * Spec-clean ASTM (E1394 / CLSI LIS02) message generation: the `H`/`P`/`O`/`R`/`C`/`L` record report,
@@ -10,7 +10,7 @@ import { Q as QuirkDescriptor, S as SynthProfile, a as QuirkArtifact, b as Quirk
10
10
  *
11
11
  * A framed **E1381 / CLSI LIS01** variant is also offered ({@link generateAstmResultFramed}) via
12
12
  * `composeAstmFrames`, which frames each record into `<STX> FN text <ETB|ETX> CS <CR><LF>` with the
13
- * **modulo-256 checksum and the `0`–`7` frame number computed by the parser**, never faked. Both round
13
+ * **modulo-256 checksum and the `0` to `7` frame number computed by the parser**, never faked. Both round
14
14
  * trip through `@cosyte/astm` cleanly (`parseAstmRecords` / `parseFramedAstm`: see `./round-trip`).
15
15
  *
16
16
  * Every value at a PHI-bearing locus (the `P` record's name / DOB / practice+lab IDs) is
@@ -24,7 +24,7 @@ import { Q as QuirkDescriptor, S as SynthProfile, a as QuirkArtifact, b as Quirk
24
24
  interface GenerateAstmOptions {
25
25
  /** The seed (deterministic: same seed yields a byte-identical message). */
26
26
  readonly seed: number;
27
- /** How many `R` (result) records to emit. Defaults to a seeded 1–4. */
27
+ /** How many `R` (result) records to emit. Defaults to a seeded 1 to 4. */
28
28
  readonly resultCount?: number;
29
29
  /** Whether to append a `C` (comment) record after the results. Defaults to `true`. */
30
30
  readonly comment?: boolean;
@@ -61,7 +61,7 @@ declare function generateAstmOrder(options: GenerateAstmOptions): string;
61
61
  /**
62
62
  * Generate a spec-clean **framed** ASTM result message: the same `H`/`P`/`O`/`R`…/`C`/`L` records,
63
63
  * wrapped in the **E1381 / CLSI LIS01** frame envelope (`<STX> FN text <ETB|ETX> CS <CR><LF>`) via
64
- * `@cosyte/astm`'s `composeAstmFrames`. The **modulo-256 checksum and the `0`–`7` frame number are
64
+ * `@cosyte/astm`'s `composeAstmFrames`. The **modulo-256 checksum and the `0` to `7` frame number are
65
65
  * computed by the parser** (never hand-written), and a record over 240 bytes is split across frames,
66
66
  * so the bytes round-trip through `parseFramedAstm` with zero frame **and** record warnings (see
67
67
  * `./round-trip`). Each record is framed independently (one `ETX`-closed run per record), mirroring what
@@ -382,7 +382,7 @@ declare const astmQuirkProfile: SynthProfile;
382
382
  * synthetic-by-construction. The practice- and laboratory-assigned patient IDs are
383
383
  * minted independently, so they stay **distinct**.
384
384
  * - **Framing (E1381):** `generateAstmResultFramed` via `composeAstmFrames`, the modulo-256 checksum
385
- * and the `0`–`7` frame number are **computed by the parser, never faked**, and the bytes round-trip
385
+ * and the `0` to `7` frame number are **computed by the parser, never faked**, and the bytes round-trip
386
386
  * through `parseFramedAstm` with zero frame **and** record warnings.
387
387
  *
388
388
  * @module
@@ -59,8 +59,7 @@ var SYNTH_FATAL_CODES = {
59
59
  * see `resolveKind`: a selector union is erased at run time, and a selector that falls through
60
60
  * either mislabels the fixture or hands the value to a peer builder that quotes it back.
61
61
  */
62
- SYNTH_UNSUPPORTED_KIND: "SYNTH_UNSUPPORTED_KIND"
63
- };
62
+ SYNTH_UNSUPPORTED_KIND: "SYNTH_UNSUPPORTED_KIND"};
64
63
  var SYNTH_FATAL_MESSAGES = Object.freeze({
65
64
  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
65
  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).",
@@ -71,7 +70,8 @@ var SYNTH_FATAL_MESSAGES = Object.freeze({
71
70
  SYNTH_INVALID_RANGE: "An integer range was requested with its maximum below its minimum.",
72
71
  SYNTH_EMPTY_POOL: "A value was drawn from an empty pool.",
73
72
  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."
73
+ 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.",
74
+ SYNTH_PROFILE_NOT_GENERATED: "The requested profile is published by the adopted implementation guide, and this build does not generate it. The coverage surface reports, per adopted profile, whether it is generated."
75
75
  });
76
76
  var SynthError = class extends Error {
77
77
  /** The stable fatal code. */
@@ -149,7 +149,7 @@ function makeCorpus(seed, artifacts, quirks = []) {
149
149
  var SYNTHETIC_ASSIGNING_AUTHORITY = Object.freeze({
150
150
  /** The human-readable assigning-authority namespace id (HL7 HD.1). */
151
151
  namespaceId: "COSYTE-SYNTH",
152
- /** The universal id, an OID under HL7's example arc `2.16.840.1.113883.19` (HD.2). */
152
+ /** The universal id, an OID this package chose under the root `2.16.840.1.113883.19` (HD.2). */
153
153
  universalId: "2.16.840.1.113883.19.999",
154
154
  /** The universal id type (HD.3). */
155
155
  universalIdType: "ISO"
@@ -168,6 +168,18 @@ var TEST_NET_V4_PREFIXES = Object.freeze([
168
168
  // TEST-NET-3
169
169
  ]);
170
170
  var DOC_V6_PREFIX = "2001:db8";
171
+ var ITIN_GROUP_RANGES = Object.freeze([
172
+ Object.freeze({ min: 50, max: 65 }),
173
+ Object.freeze({ min: 70, max: 88 }),
174
+ Object.freeze({ min: 90, max: 92 }),
175
+ Object.freeze({ min: 94, max: 99 })
176
+ ]);
177
+ var ITIN_EXCLUDED_GROUPS = Object.freeze([89, 93]);
178
+ var SSN_SYNTHETIC_GROUPS = Object.freeze(
179
+ Array.from({ length: 100 }, (_unused, group) => group).filter(
180
+ (group) => !ITIN_GROUP_RANGES.some((range) => group >= range.min && group <= range.max) && !ITIN_EXCLUDED_GROUPS.includes(group)
181
+ ).map((group) => String(group).padStart(2, "0"))
182
+ );
171
183
  var NPI_LUHN_PREFIX = "80840";
172
184
  function luhnMod10(digits) {
173
185
  let sum = 0;
@@ -276,10 +288,10 @@ var SYNTHETIC_CITY_NAMES = Object.freeze([
276
288
  // src/safe/providers.ts
277
289
  function ssn(rng, block = "never-issued") {
278
290
  if (block === "advertising") {
279
- return `987-65-432${String(rng.int(0, 9))}`;
291
+ return `987-00-432${String(rng.int(0, 9))}`;
280
292
  }
281
293
  const area = rng.int(900, 999);
282
- const group = rng.digits(2);
294
+ const group = rng.pick(SSN_SYNTHETIC_GROUPS);
283
295
  const serial = rng.digits(4);
284
296
  return `${String(area)}-${group}-${serial}`;
285
297
  }