@cosyte/synth 0.0.9 → 0.1.0

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 +73 -0
  2. package/README.md +21 -12
  3. package/dist/astm/index.cjs +18 -6
  4. package/dist/astm/index.cjs.map +1 -1
  5. package/dist/astm/index.d.cts +2 -2
  6. package/dist/astm/index.d.ts +2 -2
  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 +2 -2
  18. package/dist/deid/index.d.ts +2 -2
  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 +2 -2
  30. package/dist/hl7/index.d.ts +2 -2
  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 +172 -38
  36. package/dist/index.d.ts +172 -38
  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 +1 -1
  42. package/dist/ncpdp/index.d.ts +1 -1
  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-BQtPk3PN.d.cts} +18 -4
  46. package/dist/{providers-B9uVinAe.d.ts → providers-BQtPk3PN.d.ts} +18 -4
  47. package/dist/{quirk-HZdznAkM.d.ts → quirk-Bzx9g8KG.d.ts} +1 -1
  48. package/dist/{quirk-IaHp4z7N.d.cts → quirk-C_lZrspq.d.cts} +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 +1 -1
  52. package/dist/x12/index.d.ts +1 -1
  53. package/dist/x12/index.mjs +18 -6
  54. package/dist/x12/index.mjs.map +1 -1
  55. package/package.json +54 -30
@@ -171,9 +171,23 @@ interface SyntheticIdentifier {
171
171
  /** Which SSN reserved space to draw from. */
172
172
  type SsnBlock = "never-issued" | "advertising";
173
173
  /**
174
- * A **synthetic SSN**: dashed `AAA-GG-SSSS`. Default draws the SSA never-issued area space
175
- * (`900–999`); `block: "advertising"` draws SSA's reserved advertising block (`987-65-4320…4329`).
176
- * A value from this function can never be a real SSN.
174
+ * A **synthetic SSN**: dashed `AAA-GG-SSSS`, drawn so it can be neither an SSA-assignable Social
175
+ * Security number nor a validly formatted IRS ITIN. Two authorities share this number space: SSA
176
+ * never issues area `900-999`, and the IRS issues ITINs *inside* that area, distinguished by the
177
+ * group digits. So the area rule alone is only half the guarantee, and both blocks below also keep
178
+ * the group outside every published ITIN group range (see {@link isItinFormatted}).
179
+ *
180
+ * Default draws the never-issued area space (`900-999`) with a group from
181
+ * {@link SSN_SYNTHETIC_GROUPS}; `block: "advertising"` returns the fixed display block
182
+ * `987-00-4320` to `987-00-4329`, whose group `00` is one SSA never assigns and one no published
183
+ * ITIN range contains.
184
+ *
185
+ * **`"advertising"` no longer means SSA's own advertising block.** That published block is
186
+ * `987-65-4320` to `987-65-4329`, and group `65` sits inside a published ITIN group range, so every
187
+ * value in it is ITIN-formatted and none of them can be emitted here. The option keeps its name
188
+ * (renaming it would break call sites for a property no test asserts) and keeps its purpose, a fixed
189
+ * ten-value block safe to print on screen, but it is a display block of this package's choosing now,
190
+ * not a citation of SSA's. Do not reintroduce the `65` group to recover the provenance.
177
191
  *
178
192
  * @param rng - The seeded generator.
179
193
  * @param block - Which reserved space to draw from. Defaults to `"never-issued"`.
@@ -181,7 +195,7 @@ type SsnBlock = "never-issued" | "advertising";
181
195
  * @example
182
196
  * ```ts
183
197
  * import { createRng, ssn } from "@cosyte/synth";
184
- * ssn(createRng(1)); // e.g. a 900-area, never-issued SSN
198
+ * ssn(createRng(1)); // e.g. a 900-area, never-issued, never-ITIN-formatted SSN
185
199
  * ```
186
200
  */
187
201
  declare function ssn(rng: Rng, block?: SsnBlock): string;
@@ -171,9 +171,23 @@ interface SyntheticIdentifier {
171
171
  /** Which SSN reserved space to draw from. */
172
172
  type SsnBlock = "never-issued" | "advertising";
173
173
  /**
174
- * A **synthetic SSN**: dashed `AAA-GG-SSSS`. Default draws the SSA never-issued area space
175
- * (`900–999`); `block: "advertising"` draws SSA's reserved advertising block (`987-65-4320…4329`).
176
- * A value from this function can never be a real SSN.
174
+ * A **synthetic SSN**: dashed `AAA-GG-SSSS`, drawn so it can be neither an SSA-assignable Social
175
+ * Security number nor a validly formatted IRS ITIN. Two authorities share this number space: SSA
176
+ * never issues area `900-999`, and the IRS issues ITINs *inside* that area, distinguished by the
177
+ * group digits. So the area rule alone is only half the guarantee, and both blocks below also keep
178
+ * the group outside every published ITIN group range (see {@link isItinFormatted}).
179
+ *
180
+ * Default draws the never-issued area space (`900-999`) with a group from
181
+ * {@link SSN_SYNTHETIC_GROUPS}; `block: "advertising"` returns the fixed display block
182
+ * `987-00-4320` to `987-00-4329`, whose group `00` is one SSA never assigns and one no published
183
+ * ITIN range contains.
184
+ *
185
+ * **`"advertising"` no longer means SSA's own advertising block.** That published block is
186
+ * `987-65-4320` to `987-65-4329`, and group `65` sits inside a published ITIN group range, so every
187
+ * value in it is ITIN-formatted and none of them can be emitted here. The option keeps its name
188
+ * (renaming it would break call sites for a property no test asserts) and keeps its purpose, a fixed
189
+ * ten-value block safe to print on screen, but it is a display block of this package's choosing now,
190
+ * not a citation of SSA's. Do not reintroduce the `65` group to recover the provenance.
177
191
  *
178
192
  * @param rng - The seeded generator.
179
193
  * @param block - Which reserved space to draw from. Defaults to `"never-issued"`.
@@ -181,7 +195,7 @@ type SsnBlock = "never-issued" | "advertising";
181
195
  * @example
182
196
  * ```ts
183
197
  * import { createRng, ssn } from "@cosyte/synth";
184
- * ssn(createRng(1)); // e.g. a 900-area, never-issued SSN
198
+ * ssn(createRng(1)); // e.g. a 900-area, never-issued, never-ITIN-formatted SSN
185
199
  * ```
186
200
  */
187
201
  declare function ssn(rng: Rng, block?: SsnBlock): string;
@@ -1,4 +1,4 @@
1
- import { m as SynthFormat } from './providers-B9uVinAe.js';
1
+ import { m as SynthFormat } from './providers-BQtPk3PN.js';
2
2
 
3
3
  /**
4
4
  * `defineSynthProfile`: the growth-loop hook for site/vendor fixture recipes. A profile bundles the
@@ -1,4 +1,4 @@
1
- import { m as SynthFormat } from './providers-B9uVinAe.cjs';
1
+ import { m as SynthFormat } from './providers-BQtPk3PN.cjs';
2
2
 
3
3
  /**
4
4
  * `defineSynthProfile`: the growth-loop hook for site/vendor fixture recipes. A profile bundles the
@@ -45,8 +45,7 @@ var SYNTH_FATAL_CODES = {
45
45
  * see `resolveKind`: a selector union is erased at run time, and a selector that falls through
46
46
  * either mislabels the fixture or hands the value to a peer builder that quotes it back.
47
47
  */
48
- SYNTH_UNSUPPORTED_KIND: "SYNTH_UNSUPPORTED_KIND"
49
- };
48
+ SYNTH_UNSUPPORTED_KIND: "SYNTH_UNSUPPORTED_KIND"};
50
49
  var SYNTH_FATAL_MESSAGES = Object.freeze({
51
50
  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
51
  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).",
@@ -57,7 +56,8 @@ var SYNTH_FATAL_MESSAGES = Object.freeze({
57
56
  SYNTH_INVALID_RANGE: "An integer range was requested with its maximum below its minimum.",
58
57
  SYNTH_EMPTY_POOL: "A value was drawn from an empty pool.",
59
58
  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."
59
+ 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.",
60
+ 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."
61
61
  });
62
62
  var SynthError = class extends Error {
63
63
  /** The stable fatal code. */
@@ -143,7 +143,7 @@ function money(n) {
143
143
  var SYNTHETIC_ASSIGNING_AUTHORITY = Object.freeze({
144
144
  /** The human-readable assigning-authority namespace id (HL7 HD.1). */
145
145
  namespaceId: "COSYTE-SYNTH",
146
- /** The universal id, an OID under HL7's example arc `2.16.840.1.113883.19` (HD.2). */
146
+ /** The universal id, an OID this package chose under the root `2.16.840.1.113883.19` (HD.2). */
147
147
  universalId: "2.16.840.1.113883.19.999",
148
148
  /** The universal id type (HD.3). */
149
149
  universalIdType: "ISO"
@@ -162,6 +162,18 @@ var TEST_NET_V4_PREFIXES = Object.freeze([
162
162
  // TEST-NET-3
163
163
  ]);
164
164
  var DOC_V6_PREFIX = "2001:db8";
165
+ var ITIN_GROUP_RANGES = Object.freeze([
166
+ Object.freeze({ min: 50, max: 65 }),
167
+ Object.freeze({ min: 70, max: 88 }),
168
+ Object.freeze({ min: 90, max: 92 }),
169
+ Object.freeze({ min: 94, max: 99 })
170
+ ]);
171
+ var ITIN_EXCLUDED_GROUPS = Object.freeze([89, 93]);
172
+ var SSN_SYNTHETIC_GROUPS = Object.freeze(
173
+ Array.from({ length: 100 }, (_unused, group) => group).filter(
174
+ (group) => !ITIN_GROUP_RANGES.some((range) => group >= range.min && group <= range.max) && !ITIN_EXCLUDED_GROUPS.includes(group)
175
+ ).map((group) => String(group).padStart(2, "0"))
176
+ );
165
177
  var NPI_LUHN_PREFIX = "80840";
166
178
  function luhnMod10(digits) {
167
179
  let sum = 0;
@@ -270,10 +282,10 @@ var SYNTHETIC_CITY_NAMES = Object.freeze([
270
282
  // src/safe/providers.ts
271
283
  function ssn(rng, block = "never-issued") {
272
284
  if (block === "advertising") {
273
- return `987-65-432${String(rng.int(0, 9))}`;
285
+ return `987-00-432${String(rng.int(0, 9))}`;
274
286
  }
275
287
  const area = rng.int(900, 999);
276
- const group = rng.digits(2);
288
+ const group = rng.pick(SSN_SYNTHETIC_GROUPS);
277
289
  const serial = rng.digits(4);
278
290
  return `${String(area)}-${group}-${serial}`;
279
291
  }