@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
package/dist/index.d.cts CHANGED
@@ -1,44 +1,84 @@
1
- import { s as ssn, p as phone, n as name, e as email, i as ipv4, c as ipv6, u as uuid, d as identifier, f as address, g as dateYmd, h as npi, j as dea } from './providers-B9uVinAe.cjs';
2
- export { A as Artifact, C as Corpus, k as CorpusManifest, R as Rng, l as SsnBlock, m as SynthFormat, b as SyntheticAddress, a as SyntheticIdentifier, S as SyntheticName, o as createRng, q as makeCorpus } from './providers-B9uVinAe.cjs';
3
- export { P as PROFILE_QUIRK_APPLIED, a as QuirkArtifact, Q as QuirkDescriptor, c as QuirkProfileDisposition, d as QuirkProfiledVerdict, b as QuirkRoundTripResult, S as SynthProfile, e as SynthProfileSpec, f as assertIntendedWarnings, g as defineSynthProfile, p as profileTolerated, r as resolveQuirk, s as sameCodeSet, v as validateProfileQuirks } from './quirk-IaHp4z7N.cjs';
1
+ import { s as ssn, p as phone, n as name, e as email, i as ipv4, c as ipv6, u as uuid, d as identifier, f as address, g as dateYmd, h as npi, j as dea } from './providers-BQtPk3PN.cjs';
2
+ export { A as Artifact, C as Corpus, k as CorpusManifest, R as Rng, l as SsnBlock, m as SynthFormat, b as SyntheticAddress, a as SyntheticIdentifier, S as SyntheticName, o as createRng, q as makeCorpus } from './providers-BQtPk3PN.cjs';
3
+ export { P as PROFILE_QUIRK_APPLIED, a as QuirkArtifact, Q as QuirkDescriptor, c as QuirkProfileDisposition, d as QuirkProfiledVerdict, b as QuirkRoundTripResult, S as SynthProfile, e as SynthProfileSpec, f as assertIntendedWarnings, g as defineSynthProfile, p as profileTolerated, r as resolveQuirk, s as sameCodeSet, v as validateProfileQuirks } from './quirk-C_lZrspq.cjs';
4
4
 
5
5
  /**
6
6
  * The reserved / never-collide identifier facts that make a `@cosyte/synth` value **provably
7
7
  * synthetic**: the ground truth behind the synthetic-safety invariant.
8
8
  *
9
- * These are **facts**, not copyrighted prose: authoritative ranges published by SSA, NANPA, and the
10
- * IETF that are guaranteed never to denote a real person or a real routable resource. Every provider
11
- * draws only from these; the predicates here are the executable half of the CI synthetic-safety gate:
12
- * they let a test assert that no emitted value falls **outside** a reserved source.
9
+ * These are **facts**, not copyrighted prose: ranges and check-digit rules published by SSA, the
10
+ * IRS, HHS, NANPA and the IETF that are guaranteed never to denote a real person or a real routable
11
+ * resource. Where two authorities share one number space (SSN and ITIN), a value must be outside
12
+ * both. Every provider draws only from these; the predicates here are the executable half of the CI
13
+ * synthetic-safety gate: they let a test assert that no emitted value falls **outside** a reserved
14
+ * source.
15
+ *
16
+ * Every entry below names its authority by that authority's **own published identifier**, never by a
17
+ * bare hostname, so a reader can open the text and check the claim instead of taking this module's
18
+ * word for it. Two loci have no reserving authority and one rests on a source that is not the
19
+ * issuing agency; each says so at the point of use rather than being left out of this list.
13
20
  *
14
21
  * Sources:
15
- * - **SSN**, SSA never issues area numbers `000`, `666`, or `900–999`; the `987-65-4320…4329` block
16
- * is SSA's explicitly-reserved advertising range. (ssa.gov)
17
- * - **Phone**, NANP reserves `555-0100…555-0199` as the fictional/non-working line range. (nanpa.com)
18
- * - **Email/domain**, RFC 2606 / RFC 6761 reserved: `example.com`/`.net`/`.org` and the `.example`,
19
- * `.test`, `.invalid`, `.localhost` TLDs.
20
- * - **IP**, RFC 5737 IPv4 TEST-NET-1/2/3 (`192.0.2.0/24`, `198.51.100.0/24`, `203.0.113.0/24`) and
21
- * RFC 3849 IPv6 documentation prefix `2001:db8::/32`.
22
+ * - **SSN**, SSA POMS RM 10201.035 (Invalid Social Security Numbers (SSNs)) defines an invalid SSN
23
+ * as "one that we never assigned", and identifies one by a first three digits (former area number)
24
+ * of `000`, `666`, or "in the 900 series", or a second group of two digits (former group number)
25
+ * of `00`. <https://secure.ssa.gov/poms.nsf/lnx/0110201035>
26
+ * - **ITIN**, an IRS Individual Taxpayer Identification Number shares the SSN number space by
27
+ * construction: it is a `9NN-GG-NNNN` value whose group `GG` falls in a published ITIN group
28
+ * range. Area `900-999` alone therefore does not prove a value cannot be a federally issued
29
+ * identifier, so a synthetic SSN also keeps its group outside every published range. IRS Internal
30
+ * Revenue Manual 3.21.263: "An ITIN begins with a `9` and the 4th and 5th digits are 50-65, 70-88,
31
+ * 90-92 and 94-99". <https://www.irs.gov/irm/part3/irm_03-021-263r>
32
+ * - **Phone**, NANPA's 555 Line Numbers page: "The fictitious, non-working numbers, 555-0100 through
33
+ * 555-0199, will remain reserved for entertainment/advertising."
34
+ * <https://nanpa.com/numbering/555-line-numbers>
35
+ * - **Email/domain**, RFC 2606 (Reserved Top Level DNS Names) reserves the `.test`, `.example`,
36
+ * `.invalid` and `.localhost` top-level names and the second-level names `example.com`/`.net`/
37
+ * `.org`; RFC 6761 section 6.5 carries the example domains into the special-use registry.
38
+ * <https://datatracker.ietf.org/doc/html/rfc2606>,
39
+ * <https://datatracker.ietf.org/doc/html/rfc6761>
40
+ * - **IP**, RFC 5737: the blocks `192.0.2.0/24` (TEST-NET-1), `198.51.100.0/24` (TEST-NET-2) and
41
+ * `203.0.113.0/24` (TEST-NET-3) "are provided for use in documentation"; RFC 3849: "The prefix
42
+ * allocated for documentation purposes is 2001:DB8::/32".
43
+ * <https://datatracker.ietf.org/doc/html/rfc5737>,
44
+ * <https://datatracker.ietf.org/doc/html/rfc3849>
22
45
  * - **NPI**, a real National Provider Identifier is a 10-digit number whose last digit is a Luhn
23
- * check digit computed over the `80840` prefix + the 9-digit base (CMS NPI check-digit rule, ISO
24
- * 7812). A number whose check digit is **wrong** therefore cannot be a NPPES-issued NPI. `synth`
25
- * emits NPIs with a deliberately-invalid check digit, so no generated NPI can collide with a real
26
- * provider.
46
+ * check digit computed over the `80840` prefix + the 9-digit base. The rule is 69 FR 3434, the
47
+ * final rule adopting the NPI (FR Doc 04-1149, docket CMS-0045-F), whose issuing agency that
48
+ * document records as "Centers for Medicare & Medicaid Services, HHS": "the NPI check digit
49
+ * calculation must always be performed as though the NPI is preceded by" `80840`, and the check
50
+ * digit is "calculated using the ISO standard Luhn check digit algorithm". A number whose check
51
+ * digit is **wrong** therefore cannot be a validly issued NPI. `synth` emits NPIs with a
52
+ * deliberately-invalid check digit, so no generated NPI can collide with a real provider.
53
+ * <https://www.federalregister.gov/documents/full_text/text/2004/01/23/04-1149.txt>
54
+ * - **DEA**, the check-digit formula is **not** attributed to the DEA and no DEA-published text
55
+ * stating it is cited anywhere here. See {@link deaCheckDigit}, which names the non-normative
56
+ * source the claim does rest on, and what that source is not.
57
+ * - **MRN / member / account**, **no authority reserves this locus**: there is no reserved MRN range
58
+ * and none is claimed. See {@link SYNTHETIC_ASSIGNING_AUTHORITY} for what the floor rests on
59
+ * instead.
27
60
  *
28
61
  * @module
29
62
  */
30
63
  /**
31
64
  * The synthetic **assigning authority** `@cosyte/synth` mints MRNs / account / member identifiers
32
- * under. There is **no** reserved MRN range (an MRN is unique only within its assigning-authority /
33
- * OID namespace), so, as a documented design decision, every synthetic identifier
34
- * is scoped to a namespace that clearly cannot be a real facility's: a `SYNTH`-labelled authority whose
35
- * OID lives under HL7's designated **example** root `2.16.840.1.113883.19`. A value under this AA can
36
- * never collide with a real record because the *namespace itself* is synthetic.
65
+ * under.
66
+ *
67
+ * **No authority reserves this locus.** An MRN is unique only within its assigning-authority / OID
68
+ * namespace, no registry reserves a range of them, and none is cited here. What the floor rests on
69
+ * instead is the *namespace*, as a documented design decision: every synthetic identifier is scoped
70
+ * to a namespace that clearly cannot be a real facility's, a `SYNTH`-labelled authority this package
71
+ * mints and no real facility uses. A value under this AA can never collide with a real record
72
+ * whatever its digits are, because the namespace itself is synthetic.
73
+ *
74
+ * The OID is **uncited for the same reason**. `2.16.840.1.113883.19.999` is a value this package
75
+ * chose; no published text designating the root `2.16.840.1.113883.19` for example use could be
76
+ * shown, so this module claims no such designation and the guarantee above does not rest on one.
37
77
  */
38
78
  declare const SYNTHETIC_ASSIGNING_AUTHORITY: Readonly<{
39
79
  /** The human-readable assigning-authority namespace id (HL7 HD.1). */
40
80
  namespaceId: "COSYTE-SYNTH";
41
- /** The universal id, an OID under HL7's example arc `2.16.840.1.113883.19` (HD.2). */
81
+ /** The universal id, an OID this package chose under the root `2.16.840.1.113883.19` (HD.2). */
42
82
  universalId: "2.16.840.1.113883.19.999";
43
83
  /** The universal id type (HD.3). */
44
84
  universalIdType: "ISO";
@@ -50,9 +90,33 @@ declare const TEST_NET_V4_PREFIXES: readonly string[];
50
90
  /** RFC 3849 IPv6 documentation prefix. */
51
91
  declare const DOC_V6_PREFIX = "2001:db8";
52
92
  /**
53
- * The `80840` prefix prepended to a 10-digit NPI before the Luhn check (the CMS NPI check-digit
54
- * rule: `80840` is the ISO 7812 issuer identifier for the US health-application namespace). A real
55
- * NPI satisfies `luhn("80840" + npi) ≡ 0 (mod 10)`.
93
+ * The published **IRS ITIN group ranges**, inclusive `[min, max]` bands over the two group digits
94
+ * (positions 4 and 5) of a `9NN-GG-NNNN` value. An Individual Taxpayer Identification Number is an
95
+ * SSN-format number that begins with `9` and carries a group inside one of these bands, so these
96
+ * bands are what separates an SSN the SSA manual calls invalid from a validly formatted ITIN.
97
+ *
98
+ * These are **facts** about the number's shape, not copyrighted prose (IRS Internal Revenue Manual
99
+ * 3.21.263). Group values `89` and `93` sit between the bands on purpose: the IRM records them as
100
+ * reserved for other IRS programs rather than for ITINs, so a value carrying one is **not**
101
+ * ITIN-formatted (see {@link isItinFormatted}).
102
+ */
103
+ declare const ITIN_GROUP_RANGES: readonly Readonly<{
104
+ min: number;
105
+ max: number;
106
+ }>[];
107
+ /**
108
+ * The `80840` prefix prepended to a 10-digit NPI before the Luhn check. A real NPI satisfies
109
+ * `luhn("80840" + npi) ≡ 0 (mod 10)`.
110
+ *
111
+ * The rule is **69 FR 3434**, the final rule adopting the NPI (FR Doc 04-1149, docket CMS-0045-F),
112
+ * issued by the agency that document names as "Centers for Medicare & Medicaid Services, HHS": "the
113
+ * NPI check digit calculation must always be performed as though the NPI is preceded by" `80840`.
114
+ * The prefix itself is not that rule's: it credits the NCITS.284 standard health care identification
115
+ * card, which "requires that the first five digits of the card issuer identifier be" `80840`, "where
116
+ * the initial two digits, 80, signify health applications, the next three digits, 840, signify
117
+ * United States". The rule cites no ISO document number for the prefix or for the check digit, and
118
+ * neither does this module.
119
+ * <https://www.federalregister.gov/documents/full_text/text/2004/01/23/04-1149.txt>
56
120
  */
57
121
  declare const NPI_LUHN_PREFIX = "80840";
58
122
  /**
@@ -68,7 +132,16 @@ declare function luhnMod10(digits: string): number;
68
132
  * The correct NPI check digit for a 9-digit base: the value that makes `80840` + base + check pass
69
133
  * the Luhn check.
70
134
  *
71
- * @param base9 - The 9-digit NPI base (positions 1–9).
135
+ * The algorithm this inverts is cited: 69 FR 3434 (FR Doc 04-1149) requires the check digit to be
136
+ * "calculated using the ISO standard Luhn check digit algorithm", a modulus 10 double-add-double
137
+ * algorithm, performed as though the NPI were preceded by {@link NPI_LUHN_PREFIX}. That rule names
138
+ * the algorithm and its behaviour but no ISO document number, and points onward for the step-by-step
139
+ * form: "The specification for calculation of the NPI check digit will be made available on the CMS
140
+ * Web site". What this function implements is the rule's own description, modulus 10 Luhn over the
141
+ * prefixed digits; no separate specification is cited for it.
142
+ * <https://www.federalregister.gov/documents/full_text/text/2004/01/23/04-1149.txt>
143
+ *
144
+ * @param base9 - The 9-digit NPI base (positions 1 to 9).
72
145
  * @returns The check digit (`0`–`9`) a real NPI would carry for this base.
73
146
  * @example
74
147
  * ```ts
@@ -87,11 +160,25 @@ declare function npiCheckDigit(base9: string): number;
87
160
  */
88
161
  declare const DEA_REGISTRANT_TYPES: readonly string[];
89
162
  /**
90
- * The correct DEA check digit for a 7-digit numeric base. The published DEA checksum is
163
+ * The correct DEA check digit for a 7-digit numeric base. The checksum is
91
164
  * `(d1 + d3 + d5) + 2·(d2 + d4 + d6)`, whose **units digit** is the 7th (check) digit. A real DEA
92
165
  * number satisfies this; a number whose 7th digit differs cannot be a validly-issued DEA registration.
93
166
  *
94
- * @param base6 - The first 6 digits of the DEA number (positions 1–6).
167
+ * **NON-NORMATIVELY SOURCED, and this is the one locus in this module that is.** The formula above
168
+ * is quoted from a pharmacy journal article, Gabay, "Federal Controlled Substances Act: Controlled
169
+ * Substances Prescriptions", Hospital Pharmacy (PMC3847977): "add the sum of the first, third, and
170
+ * fifth digits to twice the sum of the second, fourth, and sixth digits. The total should be a
171
+ * number whose last digit is the same as the last digit of the DEA number."
172
+ * <https://pmc.ncbi.nlm.nih.gov/articles/PMC3847977/>
173
+ *
174
+ * **That article is not the DEA.** It is a secondary description of the agency's algorithm, not the
175
+ * agency's own statement of it, and no DEA-published text stating the algorithm is cited here. The
176
+ * consequence is stated rather than hidden: if the formula is wrong, a value this package builds to
177
+ * fail it may in fact **pass** the real check, and the generator would then emit a checksum-valid
178
+ * DEA number while {@link isSyntheticDea} asserts the opposite. Every other entry in this module's
179
+ * `Sources:` list names the issuing authority's own text; this one cannot.
180
+ *
181
+ * @param base6 - The first 6 digits of the DEA number (positions 1 to 6).
95
182
  * @returns The check digit (`0`–`9`) a real DEA number would carry for this base.
96
183
  * @example
97
184
  * ```ts
@@ -102,9 +189,15 @@ declare const DEA_REGISTRANT_TYPES: readonly string[];
102
189
  declare function deaCheckDigit(base6: string): number;
103
190
  /**
104
191
  * Whether a DEA number (`XX` + 7 digits, case-insensitive) is **provably synthetic**: its check digit
105
- * (the 7th digit) does **not** match the published DEA checksum, so it cannot be a validly-issued DEA
106
- * registration. A checksum-valid DEA number (which *could* denote a real prescriber) returns `false`; a
107
- * value that is not the DEA shape returns `false`.
192
+ * (the 7th digit) does **not** match the checksum {@link deaCheckDigit} computes, so it cannot be a
193
+ * validly-issued DEA registration. A checksum-valid DEA number (which *could* denote a real
194
+ * prescriber) returns `false`; a value that is not the DEA shape returns `false`.
195
+ *
196
+ * **NON-NORMATIVELY SOURCED.** This predicate is only as strong as the algorithm it inverts, and
197
+ * that algorithm is cited to a pharmacy journal article (PMC3847977), **not to the DEA**: no
198
+ * DEA-published statement of it is cited anywhere in this package. Read `true` as "fails the
199
+ * formula {@link deaCheckDigit} implements", never as "the DEA could not have issued this". The
200
+ * full citation and the consequence of the formula being wrong are on {@link deaCheckDigit}.
108
201
  *
109
202
  * @param value - The candidate DEA number (with or without incidental separators).
110
203
  * @returns `true` when the DEA number's checksum is wrong (never a real DEA registration).
@@ -117,9 +210,14 @@ declare function deaCheckDigit(base6: string): number;
117
210
  declare function isSyntheticDea(value: string): boolean;
118
211
  /**
119
212
  * Whether a 10-digit NPI is **provably synthetic**, i.e. its check digit is invalid, so it cannot be
120
- * a NPPES-issued NPI. A Luhn-valid 10-digit NPI (which *could* denote a real registered provider)
213
+ * a validly issued NPI. A Luhn-valid 10-digit NPI (which *could* denote a real registered provider)
121
214
  * returns `false`; a non-10-digit value returns `false` (not an NPI shape).
122
215
  *
216
+ * The check this inverts is the one 69 FR 3434 (FR Doc 04-1149) requires: the Luhn check digit,
217
+ * computed as though the NPI were preceded by {@link NPI_LUHN_PREFIX}. Unlike the DEA locus, this
218
+ * one cites the issuing rule itself.
219
+ * <https://www.federalregister.gov/documents/full_text/text/2004/01/23/04-1149.txt>
220
+ *
123
221
  * @param value - The candidate NPI (digits only, or with incidental separators).
124
222
  * @returns `true` when the NPI's check digit is wrong (never a real NPI).
125
223
  * @example
@@ -131,19 +229,46 @@ declare function isSyntheticDea(value: string): boolean;
131
229
  */
132
230
  declare function isSyntheticNpi(value: string): boolean;
133
231
  /**
134
- * Whether a `ddd-dd-dddd` (or `ddddddddd`) SSN string is drawn from an SSA never-issued / reserved
135
- * space: area `000`, `666`, or `900–999`. A real, issuable SSN returns `false`.
232
+ * Whether a `ddd-dd-dddd` (or `ddddddddd`) SSN string carries an area SSA's own manual identifies
233
+ * as **invalid**: `000`, `666`, or "in the 900 series". A real, issuable SSN returns `false`.
234
+ *
235
+ * The citable claim is SSA POMS RM 10201.035, which defines an invalid SSN as "one that we never
236
+ * assigned" and lists those three areas as identifying one. The wording here says invalid rather
237
+ * than never-issued because invalidity is what the manual states.
238
+ * <https://secure.ssa.gov/poms.nsf/lnx/0110201035>
136
239
  *
137
240
  * @param value - The candidate SSN (dashes optional).
138
241
  * @returns `true` when the SSN is provably synthetic.
139
242
  * @example
140
243
  * ```ts
141
244
  * import { isSyntheticSsn } from "@cosyte/synth";
142
- * isSyntheticSsn("900-12-3456"); // true (never issued)
245
+ * isSyntheticSsn("900-12-3456"); // true (the 900 series marks an invalid SSN)
143
246
  * isSyntheticSsn("123456789"); // false (issuable area 123)
144
247
  * ```
145
248
  */
146
249
  declare function isSyntheticSsn(value: string): boolean;
250
+ /**
251
+ * Whether a `ddd-dd-dddd` (or `ddddddddd`) value is a **validly formatted IRS ITIN**: it begins
252
+ * with `9` and its group digits (positions 4 and 5) fall inside a published ITIN group range
253
+ * ({@link ITIN_GROUP_RANGES}). This is the second issuing authority sharing the SSN number space,
254
+ * so `isSyntheticSsn(v) && !isItinFormatted(v)` is the full "cannot be a federally issued national
255
+ * id" guarantee, of which the area rule alone is only half.
256
+ *
257
+ * `true` means the value is ITIN-shaped and therefore **must not** be emitted at an SSN locus. A
258
+ * value that is not exactly 9 digits once separators are stripped returns `false` (not an SSN/ITIN
259
+ * shape) rather than throwing, as do the group values `89` and `93`, which the IRM reserves for
260
+ * other IRS programs rather than for ITINs.
261
+ *
262
+ * @param value - The candidate national id (dashes and other separators optional).
263
+ * @returns `true` when the value is formatted as a valid ITIN.
264
+ * @example
265
+ * ```ts
266
+ * import { isItinFormatted } from "@cosyte/synth";
267
+ * isItinFormatted("912-70-1234"); // true: group 70 is inside a published ITIN range
268
+ * isItinFormatted("912-66-1234"); // false: group 66 is outside every published ITIN range
269
+ * ```
270
+ */
271
+ declare function isItinFormatted(value: string): boolean;
147
272
  /**
148
273
  * Whether a phone string contains the NANP `555-0100…555-0199` reserved fictional line range.
149
274
  *
@@ -386,6 +511,15 @@ declare const SYNTH_FATAL_CODES: {
386
511
  * either mislabels the fixture or hands the value to a peer builder that quotes it back.
387
512
  */
388
513
  readonly SYNTH_UNSUPPORTED_KIND: "SYNTH_UNSUPPORTED_KIND";
514
+ /**
515
+ * A requested profile IS published by the adopted implementation guide, and this build does not
516
+ * generate it. Deliberately distinct from `SYNTH_UNSUPPORTED_KIND`, which says the name is not in
517
+ * the adopted set at all: "the guide does not publish this" and "we do not generate this yet" are
518
+ * different answers, and a caller building to a regulatory profile set has to be able to tell them
519
+ * apart without matching message text. Fatal, and raised **before** anything is generated: a
520
+ * mislabelled artifact is worse than no artifact.
521
+ */
522
+ readonly SYNTH_PROFILE_NOT_GENERATED: "SYNTH_PROFILE_NOT_GENERATED";
389
523
  };
390
524
  /**
391
525
  * A value from {@link SYNTH_FATAL_CODES}: the type carried by a thrown {@link SynthError}.
@@ -531,4 +665,4 @@ declare function resolveMix<T extends string>(allowed: readonly T[], requested:
531
665
  */
532
666
  declare const VERSION: string;
533
667
 
534
- export { DEA_REGISTRANT_TYPES, DOC_V6_PREFIX, NPI_LUHN_PREFIX, RESERVED_EMAIL_DOMAINS, SYNTHETIC_ASSIGNING_AUTHORITY, SYNTHETIC_CITY_NAMES, SYNTHETIC_FAMILY_NAMES, SYNTHETIC_GIVEN_NAMES, SYNTHETIC_STREET_NAMES, SYNTH_FATAL_CODES, SYNTH_FATAL_MESSAGES, type Sfc32State, SynthError, type SynthFatalCode, TEST_NET_V4_PREFIXES, VERSION, address, dateYmd, dea, deaCheckDigit, email, identifier, ipv4, ipv6, isSyntheticDea, isSyntheticEmail, isSyntheticIp, isSyntheticNpi, isSyntheticPhone, isSyntheticSsn, luhnMod10, name, npi, npiCheckDigit, phone, resolveKind, resolveMix, safe, sfc32Next, splitmix32, ssn, uuid };
668
+ export { DEA_REGISTRANT_TYPES, DOC_V6_PREFIX, ITIN_GROUP_RANGES, NPI_LUHN_PREFIX, RESERVED_EMAIL_DOMAINS, SYNTHETIC_ASSIGNING_AUTHORITY, SYNTHETIC_CITY_NAMES, SYNTHETIC_FAMILY_NAMES, SYNTHETIC_GIVEN_NAMES, SYNTHETIC_STREET_NAMES, SYNTH_FATAL_CODES, SYNTH_FATAL_MESSAGES, type Sfc32State, SynthError, type SynthFatalCode, TEST_NET_V4_PREFIXES, VERSION, address, dateYmd, dea, deaCheckDigit, email, identifier, ipv4, ipv6, isItinFormatted, isSyntheticDea, isSyntheticEmail, isSyntheticIp, isSyntheticNpi, isSyntheticPhone, isSyntheticSsn, luhnMod10, name, npi, npiCheckDigit, phone, resolveKind, resolveMix, safe, sfc32Next, splitmix32, ssn, uuid };
package/dist/index.d.ts CHANGED
@@ -1,44 +1,84 @@
1
- import { s as ssn, p as phone, n as name, e as email, i as ipv4, c as ipv6, u as uuid, d as identifier, f as address, g as dateYmd, h as npi, j as dea } from './providers-B9uVinAe.js';
2
- export { A as Artifact, C as Corpus, k as CorpusManifest, R as Rng, l as SsnBlock, m as SynthFormat, b as SyntheticAddress, a as SyntheticIdentifier, S as SyntheticName, o as createRng, q as makeCorpus } from './providers-B9uVinAe.js';
3
- export { P as PROFILE_QUIRK_APPLIED, a as QuirkArtifact, Q as QuirkDescriptor, c as QuirkProfileDisposition, d as QuirkProfiledVerdict, b as QuirkRoundTripResult, S as SynthProfile, e as SynthProfileSpec, f as assertIntendedWarnings, g as defineSynthProfile, p as profileTolerated, r as resolveQuirk, s as sameCodeSet, v as validateProfileQuirks } from './quirk-HZdznAkM.js';
1
+ import { s as ssn, p as phone, n as name, e as email, i as ipv4, c as ipv6, u as uuid, d as identifier, f as address, g as dateYmd, h as npi, j as dea } from './providers-BQtPk3PN.js';
2
+ export { A as Artifact, C as Corpus, k as CorpusManifest, R as Rng, l as SsnBlock, m as SynthFormat, b as SyntheticAddress, a as SyntheticIdentifier, S as SyntheticName, o as createRng, q as makeCorpus } from './providers-BQtPk3PN.js';
3
+ export { P as PROFILE_QUIRK_APPLIED, a as QuirkArtifact, Q as QuirkDescriptor, c as QuirkProfileDisposition, d as QuirkProfiledVerdict, b as QuirkRoundTripResult, S as SynthProfile, e as SynthProfileSpec, f as assertIntendedWarnings, g as defineSynthProfile, p as profileTolerated, r as resolveQuirk, s as sameCodeSet, v as validateProfileQuirks } from './quirk-Bzx9g8KG.js';
4
4
 
5
5
  /**
6
6
  * The reserved / never-collide identifier facts that make a `@cosyte/synth` value **provably
7
7
  * synthetic**: the ground truth behind the synthetic-safety invariant.
8
8
  *
9
- * These are **facts**, not copyrighted prose: authoritative ranges published by SSA, NANPA, and the
10
- * IETF that are guaranteed never to denote a real person or a real routable resource. Every provider
11
- * draws only from these; the predicates here are the executable half of the CI synthetic-safety gate:
12
- * they let a test assert that no emitted value falls **outside** a reserved source.
9
+ * These are **facts**, not copyrighted prose: ranges and check-digit rules published by SSA, the
10
+ * IRS, HHS, NANPA and the IETF that are guaranteed never to denote a real person or a real routable
11
+ * resource. Where two authorities share one number space (SSN and ITIN), a value must be outside
12
+ * both. Every provider draws only from these; the predicates here are the executable half of the CI
13
+ * synthetic-safety gate: they let a test assert that no emitted value falls **outside** a reserved
14
+ * source.
15
+ *
16
+ * Every entry below names its authority by that authority's **own published identifier**, never by a
17
+ * bare hostname, so a reader can open the text and check the claim instead of taking this module's
18
+ * word for it. Two loci have no reserving authority and one rests on a source that is not the
19
+ * issuing agency; each says so at the point of use rather than being left out of this list.
13
20
  *
14
21
  * Sources:
15
- * - **SSN**, SSA never issues area numbers `000`, `666`, or `900–999`; the `987-65-4320…4329` block
16
- * is SSA's explicitly-reserved advertising range. (ssa.gov)
17
- * - **Phone**, NANP reserves `555-0100…555-0199` as the fictional/non-working line range. (nanpa.com)
18
- * - **Email/domain**, RFC 2606 / RFC 6761 reserved: `example.com`/`.net`/`.org` and the `.example`,
19
- * `.test`, `.invalid`, `.localhost` TLDs.
20
- * - **IP**, RFC 5737 IPv4 TEST-NET-1/2/3 (`192.0.2.0/24`, `198.51.100.0/24`, `203.0.113.0/24`) and
21
- * RFC 3849 IPv6 documentation prefix `2001:db8::/32`.
22
+ * - **SSN**, SSA POMS RM 10201.035 (Invalid Social Security Numbers (SSNs)) defines an invalid SSN
23
+ * as "one that we never assigned", and identifies one by a first three digits (former area number)
24
+ * of `000`, `666`, or "in the 900 series", or a second group of two digits (former group number)
25
+ * of `00`. <https://secure.ssa.gov/poms.nsf/lnx/0110201035>
26
+ * - **ITIN**, an IRS Individual Taxpayer Identification Number shares the SSN number space by
27
+ * construction: it is a `9NN-GG-NNNN` value whose group `GG` falls in a published ITIN group
28
+ * range. Area `900-999` alone therefore does not prove a value cannot be a federally issued
29
+ * identifier, so a synthetic SSN also keeps its group outside every published range. IRS Internal
30
+ * Revenue Manual 3.21.263: "An ITIN begins with a `9` and the 4th and 5th digits are 50-65, 70-88,
31
+ * 90-92 and 94-99". <https://www.irs.gov/irm/part3/irm_03-021-263r>
32
+ * - **Phone**, NANPA's 555 Line Numbers page: "The fictitious, non-working numbers, 555-0100 through
33
+ * 555-0199, will remain reserved for entertainment/advertising."
34
+ * <https://nanpa.com/numbering/555-line-numbers>
35
+ * - **Email/domain**, RFC 2606 (Reserved Top Level DNS Names) reserves the `.test`, `.example`,
36
+ * `.invalid` and `.localhost` top-level names and the second-level names `example.com`/`.net`/
37
+ * `.org`; RFC 6761 section 6.5 carries the example domains into the special-use registry.
38
+ * <https://datatracker.ietf.org/doc/html/rfc2606>,
39
+ * <https://datatracker.ietf.org/doc/html/rfc6761>
40
+ * - **IP**, RFC 5737: the blocks `192.0.2.0/24` (TEST-NET-1), `198.51.100.0/24` (TEST-NET-2) and
41
+ * `203.0.113.0/24` (TEST-NET-3) "are provided for use in documentation"; RFC 3849: "The prefix
42
+ * allocated for documentation purposes is 2001:DB8::/32".
43
+ * <https://datatracker.ietf.org/doc/html/rfc5737>,
44
+ * <https://datatracker.ietf.org/doc/html/rfc3849>
22
45
  * - **NPI**, a real National Provider Identifier is a 10-digit number whose last digit is a Luhn
23
- * check digit computed over the `80840` prefix + the 9-digit base (CMS NPI check-digit rule, ISO
24
- * 7812). A number whose check digit is **wrong** therefore cannot be a NPPES-issued NPI. `synth`
25
- * emits NPIs with a deliberately-invalid check digit, so no generated NPI can collide with a real
26
- * provider.
46
+ * check digit computed over the `80840` prefix + the 9-digit base. The rule is 69 FR 3434, the
47
+ * final rule adopting the NPI (FR Doc 04-1149, docket CMS-0045-F), whose issuing agency that
48
+ * document records as "Centers for Medicare & Medicaid Services, HHS": "the NPI check digit
49
+ * calculation must always be performed as though the NPI is preceded by" `80840`, and the check
50
+ * digit is "calculated using the ISO standard Luhn check digit algorithm". A number whose check
51
+ * digit is **wrong** therefore cannot be a validly issued NPI. `synth` emits NPIs with a
52
+ * deliberately-invalid check digit, so no generated NPI can collide with a real provider.
53
+ * <https://www.federalregister.gov/documents/full_text/text/2004/01/23/04-1149.txt>
54
+ * - **DEA**, the check-digit formula is **not** attributed to the DEA and no DEA-published text
55
+ * stating it is cited anywhere here. See {@link deaCheckDigit}, which names the non-normative
56
+ * source the claim does rest on, and what that source is not.
57
+ * - **MRN / member / account**, **no authority reserves this locus**: there is no reserved MRN range
58
+ * and none is claimed. See {@link SYNTHETIC_ASSIGNING_AUTHORITY} for what the floor rests on
59
+ * instead.
27
60
  *
28
61
  * @module
29
62
  */
30
63
  /**
31
64
  * The synthetic **assigning authority** `@cosyte/synth` mints MRNs / account / member identifiers
32
- * under. There is **no** reserved MRN range (an MRN is unique only within its assigning-authority /
33
- * OID namespace), so, as a documented design decision, every synthetic identifier
34
- * is scoped to a namespace that clearly cannot be a real facility's: a `SYNTH`-labelled authority whose
35
- * OID lives under HL7's designated **example** root `2.16.840.1.113883.19`. A value under this AA can
36
- * never collide with a real record because the *namespace itself* is synthetic.
65
+ * under.
66
+ *
67
+ * **No authority reserves this locus.** An MRN is unique only within its assigning-authority / OID
68
+ * namespace, no registry reserves a range of them, and none is cited here. What the floor rests on
69
+ * instead is the *namespace*, as a documented design decision: every synthetic identifier is scoped
70
+ * to a namespace that clearly cannot be a real facility's, a `SYNTH`-labelled authority this package
71
+ * mints and no real facility uses. A value under this AA can never collide with a real record
72
+ * whatever its digits are, because the namespace itself is synthetic.
73
+ *
74
+ * The OID is **uncited for the same reason**. `2.16.840.1.113883.19.999` is a value this package
75
+ * chose; no published text designating the root `2.16.840.1.113883.19` for example use could be
76
+ * shown, so this module claims no such designation and the guarantee above does not rest on one.
37
77
  */
38
78
  declare const SYNTHETIC_ASSIGNING_AUTHORITY: Readonly<{
39
79
  /** The human-readable assigning-authority namespace id (HL7 HD.1). */
40
80
  namespaceId: "COSYTE-SYNTH";
41
- /** The universal id, an OID under HL7's example arc `2.16.840.1.113883.19` (HD.2). */
81
+ /** The universal id, an OID this package chose under the root `2.16.840.1.113883.19` (HD.2). */
42
82
  universalId: "2.16.840.1.113883.19.999";
43
83
  /** The universal id type (HD.3). */
44
84
  universalIdType: "ISO";
@@ -50,9 +90,33 @@ declare const TEST_NET_V4_PREFIXES: readonly string[];
50
90
  /** RFC 3849 IPv6 documentation prefix. */
51
91
  declare const DOC_V6_PREFIX = "2001:db8";
52
92
  /**
53
- * The `80840` prefix prepended to a 10-digit NPI before the Luhn check (the CMS NPI check-digit
54
- * rule: `80840` is the ISO 7812 issuer identifier for the US health-application namespace). A real
55
- * NPI satisfies `luhn("80840" + npi) ≡ 0 (mod 10)`.
93
+ * The published **IRS ITIN group ranges**, inclusive `[min, max]` bands over the two group digits
94
+ * (positions 4 and 5) of a `9NN-GG-NNNN` value. An Individual Taxpayer Identification Number is an
95
+ * SSN-format number that begins with `9` and carries a group inside one of these bands, so these
96
+ * bands are what separates an SSN the SSA manual calls invalid from a validly formatted ITIN.
97
+ *
98
+ * These are **facts** about the number's shape, not copyrighted prose (IRS Internal Revenue Manual
99
+ * 3.21.263). Group values `89` and `93` sit between the bands on purpose: the IRM records them as
100
+ * reserved for other IRS programs rather than for ITINs, so a value carrying one is **not**
101
+ * ITIN-formatted (see {@link isItinFormatted}).
102
+ */
103
+ declare const ITIN_GROUP_RANGES: readonly Readonly<{
104
+ min: number;
105
+ max: number;
106
+ }>[];
107
+ /**
108
+ * The `80840` prefix prepended to a 10-digit NPI before the Luhn check. A real NPI satisfies
109
+ * `luhn("80840" + npi) ≡ 0 (mod 10)`.
110
+ *
111
+ * The rule is **69 FR 3434**, the final rule adopting the NPI (FR Doc 04-1149, docket CMS-0045-F),
112
+ * issued by the agency that document names as "Centers for Medicare & Medicaid Services, HHS": "the
113
+ * NPI check digit calculation must always be performed as though the NPI is preceded by" `80840`.
114
+ * The prefix itself is not that rule's: it credits the NCITS.284 standard health care identification
115
+ * card, which "requires that the first five digits of the card issuer identifier be" `80840`, "where
116
+ * the initial two digits, 80, signify health applications, the next three digits, 840, signify
117
+ * United States". The rule cites no ISO document number for the prefix or for the check digit, and
118
+ * neither does this module.
119
+ * <https://www.federalregister.gov/documents/full_text/text/2004/01/23/04-1149.txt>
56
120
  */
57
121
  declare const NPI_LUHN_PREFIX = "80840";
58
122
  /**
@@ -68,7 +132,16 @@ declare function luhnMod10(digits: string): number;
68
132
  * The correct NPI check digit for a 9-digit base: the value that makes `80840` + base + check pass
69
133
  * the Luhn check.
70
134
  *
71
- * @param base9 - The 9-digit NPI base (positions 1–9).
135
+ * The algorithm this inverts is cited: 69 FR 3434 (FR Doc 04-1149) requires the check digit to be
136
+ * "calculated using the ISO standard Luhn check digit algorithm", a modulus 10 double-add-double
137
+ * algorithm, performed as though the NPI were preceded by {@link NPI_LUHN_PREFIX}. That rule names
138
+ * the algorithm and its behaviour but no ISO document number, and points onward for the step-by-step
139
+ * form: "The specification for calculation of the NPI check digit will be made available on the CMS
140
+ * Web site". What this function implements is the rule's own description, modulus 10 Luhn over the
141
+ * prefixed digits; no separate specification is cited for it.
142
+ * <https://www.federalregister.gov/documents/full_text/text/2004/01/23/04-1149.txt>
143
+ *
144
+ * @param base9 - The 9-digit NPI base (positions 1 to 9).
72
145
  * @returns The check digit (`0`–`9`) a real NPI would carry for this base.
73
146
  * @example
74
147
  * ```ts
@@ -87,11 +160,25 @@ declare function npiCheckDigit(base9: string): number;
87
160
  */
88
161
  declare const DEA_REGISTRANT_TYPES: readonly string[];
89
162
  /**
90
- * The correct DEA check digit for a 7-digit numeric base. The published DEA checksum is
163
+ * The correct DEA check digit for a 7-digit numeric base. The checksum is
91
164
  * `(d1 + d3 + d5) + 2·(d2 + d4 + d6)`, whose **units digit** is the 7th (check) digit. A real DEA
92
165
  * number satisfies this; a number whose 7th digit differs cannot be a validly-issued DEA registration.
93
166
  *
94
- * @param base6 - The first 6 digits of the DEA number (positions 1–6).
167
+ * **NON-NORMATIVELY SOURCED, and this is the one locus in this module that is.** The formula above
168
+ * is quoted from a pharmacy journal article, Gabay, "Federal Controlled Substances Act: Controlled
169
+ * Substances Prescriptions", Hospital Pharmacy (PMC3847977): "add the sum of the first, third, and
170
+ * fifth digits to twice the sum of the second, fourth, and sixth digits. The total should be a
171
+ * number whose last digit is the same as the last digit of the DEA number."
172
+ * <https://pmc.ncbi.nlm.nih.gov/articles/PMC3847977/>
173
+ *
174
+ * **That article is not the DEA.** It is a secondary description of the agency's algorithm, not the
175
+ * agency's own statement of it, and no DEA-published text stating the algorithm is cited here. The
176
+ * consequence is stated rather than hidden: if the formula is wrong, a value this package builds to
177
+ * fail it may in fact **pass** the real check, and the generator would then emit a checksum-valid
178
+ * DEA number while {@link isSyntheticDea} asserts the opposite. Every other entry in this module's
179
+ * `Sources:` list names the issuing authority's own text; this one cannot.
180
+ *
181
+ * @param base6 - The first 6 digits of the DEA number (positions 1 to 6).
95
182
  * @returns The check digit (`0`–`9`) a real DEA number would carry for this base.
96
183
  * @example
97
184
  * ```ts
@@ -102,9 +189,15 @@ declare const DEA_REGISTRANT_TYPES: readonly string[];
102
189
  declare function deaCheckDigit(base6: string): number;
103
190
  /**
104
191
  * Whether a DEA number (`XX` + 7 digits, case-insensitive) is **provably synthetic**: its check digit
105
- * (the 7th digit) does **not** match the published DEA checksum, so it cannot be a validly-issued DEA
106
- * registration. A checksum-valid DEA number (which *could* denote a real prescriber) returns `false`; a
107
- * value that is not the DEA shape returns `false`.
192
+ * (the 7th digit) does **not** match the checksum {@link deaCheckDigit} computes, so it cannot be a
193
+ * validly-issued DEA registration. A checksum-valid DEA number (which *could* denote a real
194
+ * prescriber) returns `false`; a value that is not the DEA shape returns `false`.
195
+ *
196
+ * **NON-NORMATIVELY SOURCED.** This predicate is only as strong as the algorithm it inverts, and
197
+ * that algorithm is cited to a pharmacy journal article (PMC3847977), **not to the DEA**: no
198
+ * DEA-published statement of it is cited anywhere in this package. Read `true` as "fails the
199
+ * formula {@link deaCheckDigit} implements", never as "the DEA could not have issued this". The
200
+ * full citation and the consequence of the formula being wrong are on {@link deaCheckDigit}.
108
201
  *
109
202
  * @param value - The candidate DEA number (with or without incidental separators).
110
203
  * @returns `true` when the DEA number's checksum is wrong (never a real DEA registration).
@@ -117,9 +210,14 @@ declare function deaCheckDigit(base6: string): number;
117
210
  declare function isSyntheticDea(value: string): boolean;
118
211
  /**
119
212
  * Whether a 10-digit NPI is **provably synthetic**, i.e. its check digit is invalid, so it cannot be
120
- * a NPPES-issued NPI. A Luhn-valid 10-digit NPI (which *could* denote a real registered provider)
213
+ * a validly issued NPI. A Luhn-valid 10-digit NPI (which *could* denote a real registered provider)
121
214
  * returns `false`; a non-10-digit value returns `false` (not an NPI shape).
122
215
  *
216
+ * The check this inverts is the one 69 FR 3434 (FR Doc 04-1149) requires: the Luhn check digit,
217
+ * computed as though the NPI were preceded by {@link NPI_LUHN_PREFIX}. Unlike the DEA locus, this
218
+ * one cites the issuing rule itself.
219
+ * <https://www.federalregister.gov/documents/full_text/text/2004/01/23/04-1149.txt>
220
+ *
123
221
  * @param value - The candidate NPI (digits only, or with incidental separators).
124
222
  * @returns `true` when the NPI's check digit is wrong (never a real NPI).
125
223
  * @example
@@ -131,19 +229,46 @@ declare function isSyntheticDea(value: string): boolean;
131
229
  */
132
230
  declare function isSyntheticNpi(value: string): boolean;
133
231
  /**
134
- * Whether a `ddd-dd-dddd` (or `ddddddddd`) SSN string is drawn from an SSA never-issued / reserved
135
- * space: area `000`, `666`, or `900–999`. A real, issuable SSN returns `false`.
232
+ * Whether a `ddd-dd-dddd` (or `ddddddddd`) SSN string carries an area SSA's own manual identifies
233
+ * as **invalid**: `000`, `666`, or "in the 900 series". A real, issuable SSN returns `false`.
234
+ *
235
+ * The citable claim is SSA POMS RM 10201.035, which defines an invalid SSN as "one that we never
236
+ * assigned" and lists those three areas as identifying one. The wording here says invalid rather
237
+ * than never-issued because invalidity is what the manual states.
238
+ * <https://secure.ssa.gov/poms.nsf/lnx/0110201035>
136
239
  *
137
240
  * @param value - The candidate SSN (dashes optional).
138
241
  * @returns `true` when the SSN is provably synthetic.
139
242
  * @example
140
243
  * ```ts
141
244
  * import { isSyntheticSsn } from "@cosyte/synth";
142
- * isSyntheticSsn("900-12-3456"); // true (never issued)
245
+ * isSyntheticSsn("900-12-3456"); // true (the 900 series marks an invalid SSN)
143
246
  * isSyntheticSsn("123456789"); // false (issuable area 123)
144
247
  * ```
145
248
  */
146
249
  declare function isSyntheticSsn(value: string): boolean;
250
+ /**
251
+ * Whether a `ddd-dd-dddd` (or `ddddddddd`) value is a **validly formatted IRS ITIN**: it begins
252
+ * with `9` and its group digits (positions 4 and 5) fall inside a published ITIN group range
253
+ * ({@link ITIN_GROUP_RANGES}). This is the second issuing authority sharing the SSN number space,
254
+ * so `isSyntheticSsn(v) && !isItinFormatted(v)` is the full "cannot be a federally issued national
255
+ * id" guarantee, of which the area rule alone is only half.
256
+ *
257
+ * `true` means the value is ITIN-shaped and therefore **must not** be emitted at an SSN locus. A
258
+ * value that is not exactly 9 digits once separators are stripped returns `false` (not an SSN/ITIN
259
+ * shape) rather than throwing, as do the group values `89` and `93`, which the IRM reserves for
260
+ * other IRS programs rather than for ITINs.
261
+ *
262
+ * @param value - The candidate national id (dashes and other separators optional).
263
+ * @returns `true` when the value is formatted as a valid ITIN.
264
+ * @example
265
+ * ```ts
266
+ * import { isItinFormatted } from "@cosyte/synth";
267
+ * isItinFormatted("912-70-1234"); // true: group 70 is inside a published ITIN range
268
+ * isItinFormatted("912-66-1234"); // false: group 66 is outside every published ITIN range
269
+ * ```
270
+ */
271
+ declare function isItinFormatted(value: string): boolean;
147
272
  /**
148
273
  * Whether a phone string contains the NANP `555-0100…555-0199` reserved fictional line range.
149
274
  *
@@ -386,6 +511,15 @@ declare const SYNTH_FATAL_CODES: {
386
511
  * either mislabels the fixture or hands the value to a peer builder that quotes it back.
387
512
  */
388
513
  readonly SYNTH_UNSUPPORTED_KIND: "SYNTH_UNSUPPORTED_KIND";
514
+ /**
515
+ * A requested profile IS published by the adopted implementation guide, and this build does not
516
+ * generate it. Deliberately distinct from `SYNTH_UNSUPPORTED_KIND`, which says the name is not in
517
+ * the adopted set at all: "the guide does not publish this" and "we do not generate this yet" are
518
+ * different answers, and a caller building to a regulatory profile set has to be able to tell them
519
+ * apart without matching message text. Fatal, and raised **before** anything is generated: a
520
+ * mislabelled artifact is worse than no artifact.
521
+ */
522
+ readonly SYNTH_PROFILE_NOT_GENERATED: "SYNTH_PROFILE_NOT_GENERATED";
389
523
  };
390
524
  /**
391
525
  * A value from {@link SYNTH_FATAL_CODES}: the type carried by a thrown {@link SynthError}.
@@ -531,4 +665,4 @@ declare function resolveMix<T extends string>(allowed: readonly T[], requested:
531
665
  */
532
666
  declare const VERSION: string;
533
667
 
534
- export { DEA_REGISTRANT_TYPES, DOC_V6_PREFIX, NPI_LUHN_PREFIX, RESERVED_EMAIL_DOMAINS, SYNTHETIC_ASSIGNING_AUTHORITY, SYNTHETIC_CITY_NAMES, SYNTHETIC_FAMILY_NAMES, SYNTHETIC_GIVEN_NAMES, SYNTHETIC_STREET_NAMES, SYNTH_FATAL_CODES, SYNTH_FATAL_MESSAGES, type Sfc32State, SynthError, type SynthFatalCode, TEST_NET_V4_PREFIXES, VERSION, address, dateYmd, dea, deaCheckDigit, email, identifier, ipv4, ipv6, isSyntheticDea, isSyntheticEmail, isSyntheticIp, isSyntheticNpi, isSyntheticPhone, isSyntheticSsn, luhnMod10, name, npi, npiCheckDigit, phone, resolveKind, resolveMix, safe, sfc32Next, splitmix32, ssn, uuid };
668
+ export { DEA_REGISTRANT_TYPES, DOC_V6_PREFIX, ITIN_GROUP_RANGES, NPI_LUHN_PREFIX, RESERVED_EMAIL_DOMAINS, SYNTHETIC_ASSIGNING_AUTHORITY, SYNTHETIC_CITY_NAMES, SYNTHETIC_FAMILY_NAMES, SYNTHETIC_GIVEN_NAMES, SYNTHETIC_STREET_NAMES, SYNTH_FATAL_CODES, SYNTH_FATAL_MESSAGES, type Sfc32State, SynthError, type SynthFatalCode, TEST_NET_V4_PREFIXES, VERSION, address, dateYmd, dea, deaCheckDigit, email, identifier, ipv4, ipv6, isItinFormatted, isSyntheticDea, isSyntheticEmail, isSyntheticIp, isSyntheticNpi, isSyntheticPhone, isSyntheticSsn, luhnMod10, name, npi, npiCheckDigit, phone, resolveKind, resolveMix, safe, sfc32Next, splitmix32, ssn, uuid };