@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.
- package/CHANGELOG.md +73 -0
- package/README.md +21 -12
- package/dist/astm/index.cjs +18 -6
- package/dist/astm/index.cjs.map +1 -1
- package/dist/astm/index.d.cts +2 -2
- package/dist/astm/index.d.ts +2 -2
- package/dist/astm/index.mjs +18 -6
- package/dist/astm/index.mjs.map +1 -1
- package/dist/ccda/index.cjs +23 -7
- package/dist/ccda/index.cjs.map +1 -1
- package/dist/ccda/index.d.cts +2 -2
- package/dist/ccda/index.d.ts +2 -2
- package/dist/ccda/index.mjs +23 -7
- package/dist/ccda/index.mjs.map +1 -1
- package/dist/deid/index.cjs +26 -8
- package/dist/deid/index.cjs.map +1 -1
- package/dist/deid/index.d.cts +2 -2
- package/dist/deid/index.d.ts +2 -2
- package/dist/deid/index.mjs +26 -8
- package/dist/deid/index.mjs.map +1 -1
- package/dist/fhir/index.cjs +174 -7
- package/dist/fhir/index.cjs.map +1 -1
- package/dist/fhir/index.d.cts +163 -2
- package/dist/fhir/index.d.ts +163 -2
- package/dist/fhir/index.mjs +171 -9
- package/dist/fhir/index.mjs.map +1 -1
- package/dist/hl7/index.cjs +18 -6
- package/dist/hl7/index.cjs.map +1 -1
- package/dist/hl7/index.d.cts +2 -2
- package/dist/hl7/index.d.ts +2 -2
- package/dist/hl7/index.mjs +18 -6
- package/dist/hl7/index.mjs.map +1 -1
- package/dist/index.cjs +37 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +172 -38
- package/dist/index.d.ts +172 -38
- package/dist/index.mjs +36 -7
- package/dist/index.mjs.map +1 -1
- package/dist/ncpdp/index.cjs +18 -6
- package/dist/ncpdp/index.cjs.map +1 -1
- package/dist/ncpdp/index.d.cts +1 -1
- package/dist/ncpdp/index.d.ts +1 -1
- package/dist/ncpdp/index.mjs +18 -6
- package/dist/ncpdp/index.mjs.map +1 -1
- package/dist/{providers-B9uVinAe.d.cts → providers-BQtPk3PN.d.cts} +18 -4
- package/dist/{providers-B9uVinAe.d.ts → providers-BQtPk3PN.d.ts} +18 -4
- package/dist/{quirk-HZdznAkM.d.ts → quirk-Bzx9g8KG.d.ts} +1 -1
- package/dist/{quirk-IaHp4z7N.d.cts → quirk-C_lZrspq.d.cts} +1 -1
- package/dist/x12/index.cjs +18 -6
- package/dist/x12/index.cjs.map +1 -1
- package/dist/x12/index.d.cts +1 -1
- package/dist/x12/index.d.ts +1 -1
- package/dist/x12/index.mjs +18 -6
- package/dist/x12/index.mjs.map +1 -1
- 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-
|
|
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-
|
|
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-
|
|
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:
|
|
10
|
-
* IETF that are guaranteed never to denote a real person or a real routable
|
|
11
|
-
*
|
|
12
|
-
*
|
|
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
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
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
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
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.
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
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
|
|
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
|
|
54
|
-
*
|
|
55
|
-
*
|
|
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
|
-
*
|
|
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
|
|
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
|
-
*
|
|
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
|
|
106
|
-
* registration. A checksum-valid DEA number (which *could* denote a real
|
|
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
|
|
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
|
|
135
|
-
*
|
|
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 (
|
|
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-
|
|
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-
|
|
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-
|
|
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:
|
|
10
|
-
* IETF that are guaranteed never to denote a real person or a real routable
|
|
11
|
-
*
|
|
12
|
-
*
|
|
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
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
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
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
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.
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
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
|
|
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
|
|
54
|
-
*
|
|
55
|
-
*
|
|
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
|
-
*
|
|
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
|
|
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
|
-
*
|
|
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
|
|
106
|
-
* registration. A checksum-valid DEA number (which *could* denote a real
|
|
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
|
|
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
|
|
135
|
-
*
|
|
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 (
|
|
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 };
|