@cosyte/synth 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +414 -0
- package/LICENSE +21 -0
- package/README.md +325 -0
- package/dist/astm/index.cjs +847 -0
- package/dist/astm/index.cjs.map +1 -0
- package/dist/astm/index.d.cts +418 -0
- package/dist/astm/index.d.ts +418 -0
- package/dist/astm/index.mjs +828 -0
- package/dist/astm/index.mjs.map +1 -0
- package/dist/ccda/index.cjs +1103 -0
- package/dist/ccda/index.cjs.map +1 -0
- package/dist/ccda/index.d.cts +380 -0
- package/dist/ccda/index.d.ts +380 -0
- package/dist/ccda/index.mjs +1077 -0
- package/dist/ccda/index.mjs.map +1 -0
- package/dist/deid/index.cjs +2809 -0
- package/dist/deid/index.cjs.map +1 -0
- package/dist/deid/index.d.cts +464 -0
- package/dist/deid/index.d.ts +464 -0
- package/dist/deid/index.mjs +2793 -0
- package/dist/deid/index.mjs.map +1 -0
- package/dist/example-codes-DeXcnCSK.d.cts +105 -0
- package/dist/example-codes-DeXcnCSK.d.ts +105 -0
- package/dist/fhir/index.cjs +1429 -0
- package/dist/fhir/index.cjs.map +1 -0
- package/dist/fhir/index.d.cts +772 -0
- package/dist/fhir/index.d.ts +772 -0
- package/dist/fhir/index.mjs +1384 -0
- package/dist/fhir/index.mjs.map +1 -0
- package/dist/hl7/index.cjs +1012 -0
- package/dist/hl7/index.cjs.map +1 -0
- package/dist/hl7/index.d.cts +548 -0
- package/dist/hl7/index.d.ts +548 -0
- package/dist/hl7/index.mjs +990 -0
- package/dist/hl7/index.mjs.map +1 -0
- package/dist/index.cjs +535 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +407 -0
- package/dist/index.d.ts +407 -0
- package/dist/index.mjs +488 -0
- package/dist/index.mjs.map +1 -0
- package/dist/ncpdp/index.cjs +714 -0
- package/dist/ncpdp/index.cjs.map +1 -0
- package/dist/ncpdp/index.d.cts +432 -0
- package/dist/ncpdp/index.d.ts +432 -0
- package/dist/ncpdp/index.mjs +695 -0
- package/dist/ncpdp/index.mjs.map +1 -0
- package/dist/providers-OLz3zAc-.d.cts +343 -0
- package/dist/providers-OLz3zAc-.d.ts +343 -0
- package/dist/quirk-DmkgoZdh.d.cts +239 -0
- package/dist/quirk-JLyO1Ncj.d.ts +239 -0
- package/dist/x12/index.cjs +920 -0
- package/dist/x12/index.cjs.map +1 -0
- package/dist/x12/index.d.cts +484 -0
- package/dist/x12/index.d.ts +484 -0
- package/dist/x12/index.mjs +892 -0
- package/dist/x12/index.mjs.map +1 -0
- package/package.json +210 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,407 @@
|
|
|
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-OLz3zAc-.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-OLz3zAc-.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-JLyO1Ncj.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The reserved / never-collide identifier facts that make a `@cosyte/synth` value **provably
|
|
7
|
+
* synthetic** — the ground truth behind the synthetic-safety invariant.
|
|
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.
|
|
13
|
+
*
|
|
14
|
+
* 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
|
+
* - **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.
|
|
27
|
+
*
|
|
28
|
+
* @module
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* 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 — 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.
|
|
37
|
+
*/
|
|
38
|
+
declare const SYNTHETIC_ASSIGNING_AUTHORITY: Readonly<{
|
|
39
|
+
/** The human-readable assigning-authority namespace id (HL7 HD.1). */
|
|
40
|
+
namespaceId: "COSYTE-SYNTH";
|
|
41
|
+
/** The universal id — an OID under HL7's example arc `2.16.840.1.113883.19` (HD.2). */
|
|
42
|
+
universalId: "2.16.840.1.113883.19.999";
|
|
43
|
+
/** The universal id type (HD.3). */
|
|
44
|
+
universalIdType: "ISO";
|
|
45
|
+
}>;
|
|
46
|
+
/** RFC 2606 / 6761 reserved email domains `@cosyte/synth` draws from. */
|
|
47
|
+
declare const RESERVED_EMAIL_DOMAINS: readonly string[];
|
|
48
|
+
/** RFC 5737 IPv4 documentation (TEST-NET) `/24` network prefixes. */
|
|
49
|
+
declare const TEST_NET_V4_PREFIXES: readonly string[];
|
|
50
|
+
/** RFC 3849 IPv6 documentation prefix. */
|
|
51
|
+
declare const DOC_V6_PREFIX = "2001:db8";
|
|
52
|
+
/**
|
|
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)`.
|
|
56
|
+
*/
|
|
57
|
+
declare const NPI_LUHN_PREFIX = "80840";
|
|
58
|
+
/**
|
|
59
|
+
* The Luhn sum (mod 10) of a numeric string, doubling every second digit from the right. Used to
|
|
60
|
+
* verify (or deliberately break) an NPI check digit.
|
|
61
|
+
*
|
|
62
|
+
* @param digits - A string of decimal digits.
|
|
63
|
+
* @returns The Luhn sum modulo 10 (0 ⇒ the string passes the Luhn check).
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
66
|
+
declare function luhnMod10(digits: string): number;
|
|
67
|
+
/**
|
|
68
|
+
* The correct NPI check digit for a 9-digit base — the value that makes `80840` + base + check pass
|
|
69
|
+
* the Luhn check.
|
|
70
|
+
*
|
|
71
|
+
* @param base9 - The 9-digit NPI base (positions 1–9).
|
|
72
|
+
* @returns The check digit (`0`–`9`) a real NPI would carry for this base.
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* import { npiCheckDigit } from "@cosyte/synth";
|
|
76
|
+
* npiCheckDigit("123456789"); // 3 — so 1234567893 is a Luhn-valid NPI shape
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
declare function npiCheckDigit(base9: string): number;
|
|
80
|
+
/**
|
|
81
|
+
* The DEA-registration prefix letters `@cosyte/synth` draws a synthetic DEA number's first character
|
|
82
|
+
* from. A real DEA number is `<registrant-type><last-name-initial>` + 7 digits; the first letter is the
|
|
83
|
+
* registrant type (A/B/F/G/M/P/R/X are the widely-published values; the second letter is the
|
|
84
|
+
* registrant's last-name initial). These letters are a **fact** about the number's shape, not
|
|
85
|
+
* copyrighted prose — they only shape the value; the synthetic guarantee is the deliberately-**invalid
|
|
86
|
+
* checksum** (see {@link dea} / {@link isSyntheticDea}).
|
|
87
|
+
*/
|
|
88
|
+
declare const DEA_REGISTRANT_TYPES: readonly string[];
|
|
89
|
+
/**
|
|
90
|
+
* The correct DEA check digit for a 7-digit numeric base. The published DEA checksum is
|
|
91
|
+
* `(d1 + d3 + d5) + 2·(d2 + d4 + d6)`, whose **units digit** is the 7th (check) digit. A real DEA
|
|
92
|
+
* number satisfies this; a number whose 7th digit differs cannot be a validly-issued DEA registration.
|
|
93
|
+
*
|
|
94
|
+
* @param base6 - The first 6 digits of the DEA number (positions 1–6).
|
|
95
|
+
* @returns The check digit (`0`–`9`) a real DEA number would carry for this base.
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* import { deaCheckDigit } from "@cosyte/synth";
|
|
99
|
+
* deaCheckDigit("123456"); // the units digit of (1+3+5) + 2·(2+4+6)
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
declare function deaCheckDigit(base6: string): number;
|
|
103
|
+
/**
|
|
104
|
+
* 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`.
|
|
108
|
+
*
|
|
109
|
+
* @param value - The candidate DEA number (with or without incidental separators).
|
|
110
|
+
* @returns `true` when the DEA number's checksum is wrong (never a real DEA registration).
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* import { isSyntheticDea } from "@cosyte/synth";
|
|
114
|
+
* isSyntheticDea("AF1234561"); // depends on the base — true when the 7th digit is wrong
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
declare function isSyntheticDea(value: string): boolean;
|
|
118
|
+
/**
|
|
119
|
+
* 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)
|
|
121
|
+
* returns `false`; a non-10-digit value returns `false` (not an NPI shape).
|
|
122
|
+
*
|
|
123
|
+
* @param value - The candidate NPI (digits only, or with incidental separators).
|
|
124
|
+
* @returns `true` when the NPI's check digit is wrong (never a real NPI).
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* import { isSyntheticNpi } from "@cosyte/synth";
|
|
128
|
+
* isSyntheticNpi("1234567894"); // true — invalid check digit (valid would be 1234567893)
|
|
129
|
+
* isSyntheticNpi("1234567893"); // false — Luhn-valid, could be a real NPI
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
declare function isSyntheticNpi(value: string): boolean;
|
|
133
|
+
/**
|
|
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`.
|
|
136
|
+
*
|
|
137
|
+
* @param value - The candidate SSN (dashes optional).
|
|
138
|
+
* @returns `true` when the SSN is provably synthetic.
|
|
139
|
+
* @example
|
|
140
|
+
* ```ts
|
|
141
|
+
* import { isSyntheticSsn } from "@cosyte/synth";
|
|
142
|
+
* isSyntheticSsn("900-12-3456"); // true (never issued)
|
|
143
|
+
* isSyntheticSsn("123456789"); // false (issuable area 123)
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
declare function isSyntheticSsn(value: string): boolean;
|
|
147
|
+
/**
|
|
148
|
+
* Whether a phone string contains the NANP `555-0100…555-0199` reserved fictional line range.
|
|
149
|
+
*
|
|
150
|
+
* @param value - The candidate phone (any formatting).
|
|
151
|
+
* @returns `true` when the number is in the reserved fictional block.
|
|
152
|
+
* @example
|
|
153
|
+
* ```ts
|
|
154
|
+
* import { isSyntheticPhone } from "@cosyte/synth";
|
|
155
|
+
* isSyntheticPhone("(202) 555-0142"); // true
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
declare function isSyntheticPhone(value: string): boolean;
|
|
159
|
+
/**
|
|
160
|
+
* Whether an email's domain is an RFC 2606 / 6761 reserved / test domain.
|
|
161
|
+
*
|
|
162
|
+
* @param value - The candidate email address.
|
|
163
|
+
* @returns `true` when the domain is reserved (never real).
|
|
164
|
+
* @example
|
|
165
|
+
* ```ts
|
|
166
|
+
* import { isSyntheticEmail } from "@cosyte/synth";
|
|
167
|
+
* isSyntheticEmail("faux.testerson@example.com"); // true
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
declare function isSyntheticEmail(value: string): boolean;
|
|
171
|
+
/**
|
|
172
|
+
* Whether an IP string is in an RFC 5737 (IPv4 TEST-NET) or RFC 3849 (IPv6 documentation) reserved
|
|
173
|
+
* block. A real routable address returns `false`.
|
|
174
|
+
*
|
|
175
|
+
* @param value - The candidate IPv4 or IPv6 address.
|
|
176
|
+
* @returns `true` when the address is a reserved documentation address.
|
|
177
|
+
* @example
|
|
178
|
+
* ```ts
|
|
179
|
+
* import { isSyntheticIp } from "@cosyte/synth";
|
|
180
|
+
* isSyntheticIp("192.0.2.44"); // true (TEST-NET-1)
|
|
181
|
+
* isSyntheticIp("8.8.8.8"); // false (real)
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
declare function isSyntheticIp(value: string): boolean;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* The shipped **clearly-fake name pool** — `@cosyte/synth`'s own license-clean synthetic data.
|
|
188
|
+
*
|
|
189
|
+
* Deliberately **not** a `faker`-style realistic-name corpus (which could match a real person at a real
|
|
190
|
+
* address — the exact hazard the synthetic-safety invariant forbids). Every token is
|
|
191
|
+
* an obviously-invented, fixture-flavoured word: a reader can tell at a glance it names no one. The pool
|
|
192
|
+
* is small on purpose — structural coverage, not demographic realism, is the goal.
|
|
193
|
+
*
|
|
194
|
+
* `# synthetic: true`
|
|
195
|
+
*
|
|
196
|
+
* @module
|
|
197
|
+
*/
|
|
198
|
+
/** Obviously-synthetic given names. None is a plausible real person's name. */
|
|
199
|
+
declare const SYNTHETIC_GIVEN_NAMES: readonly string[];
|
|
200
|
+
/** Obviously-synthetic family names. None is a plausible real surname at a real address. */
|
|
201
|
+
declare const SYNTHETIC_FAMILY_NAMES: readonly string[];
|
|
202
|
+
/** Obviously-synthetic street names for structured address fields. */
|
|
203
|
+
declare const SYNTHETIC_STREET_NAMES: readonly string[];
|
|
204
|
+
/**
|
|
205
|
+
* Obviously-synthetic city names. Combined only ever with a synthetic street + a fake name (the
|
|
206
|
+
* *combination* is what identifies, and the combination is always synthetic).
|
|
207
|
+
*/
|
|
208
|
+
declare const SYNTHETIC_CITY_NAMES: readonly string[];
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* The `safe` namespace — the single entry point for every synthetic-by-construction value provider.
|
|
212
|
+
*
|
|
213
|
+
* Grouped under one object so a consumer reads `safe.ssn(rng)` / `safe.phone(rng)` and it is
|
|
214
|
+
* self-evident that the value is drawn from a guaranteed-non-colliding synthetic source.
|
|
215
|
+
* The individual functions and the reserved-range predicates are also exported by name from the
|
|
216
|
+
* package root for direct import.
|
|
217
|
+
*
|
|
218
|
+
* @module
|
|
219
|
+
*/
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* The synthetic-safety provider namespace. Every function draws only from a reserved range or the
|
|
223
|
+
* shipped fake-name pool — no value it returns can be real or plausibly-real PHI.
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* ```ts
|
|
227
|
+
* import { createRng, safe } from "@cosyte/synth";
|
|
228
|
+
* const rng = createRng(42);
|
|
229
|
+
* safe.ssn(rng); // never-issued SSN
|
|
230
|
+
* safe.phone(rng); // reserved 555-01NN number
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
declare const safe: Readonly<{
|
|
234
|
+
ssn: typeof ssn;
|
|
235
|
+
phone: typeof phone;
|
|
236
|
+
name: typeof name;
|
|
237
|
+
email: typeof email;
|
|
238
|
+
ipv4: typeof ipv4;
|
|
239
|
+
ipv6: typeof ipv6;
|
|
240
|
+
uuid: typeof uuid;
|
|
241
|
+
identifier: typeof identifier;
|
|
242
|
+
address: typeof address;
|
|
243
|
+
dateYmd: typeof dateYmd;
|
|
244
|
+
npi: typeof npi;
|
|
245
|
+
dea: typeof dea;
|
|
246
|
+
}>;
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* `splitmix32` — a tiny, well-studied 32-bit mixing PRNG used **only** to expand a single integer
|
|
250
|
+
* seed into the four 32-bit state words that seed {@link ../rng/sfc32.sfc32}. It is not the corpus
|
|
251
|
+
* generator itself (that is `sfc32`); it exists so that a one-number seed deterministically produces a
|
|
252
|
+
* well-distributed 128-bit `sfc32` state, avoiding the poor low-bit behavior of naive
|
|
253
|
+
* `state = seed`-style initialization.
|
|
254
|
+
*
|
|
255
|
+
* Zero-dependency, `Math.random`-free (lint-enforced): the whole point of the library is that a seed —
|
|
256
|
+
* and only the seed — determines the output, on any machine, any run.
|
|
257
|
+
*
|
|
258
|
+
* @module
|
|
259
|
+
*/
|
|
260
|
+
/**
|
|
261
|
+
* A stateful `splitmix32` step function. Each call advances the internal 32-bit state and returns the
|
|
262
|
+
* next unsigned 32-bit integer. Deterministic for a given seed.
|
|
263
|
+
*
|
|
264
|
+
* @param seed - The 32-bit seed. Coerced to a 32-bit integer via `| 0`.
|
|
265
|
+
* @returns A nullary function returning the next `uint32` in the stream.
|
|
266
|
+
* @example
|
|
267
|
+
* ```ts
|
|
268
|
+
* import { splitmix32 } from "@cosyte/synth";
|
|
269
|
+
* const next = splitmix32(12345);
|
|
270
|
+
* const a = next(); // deterministic uint32
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
273
|
+
declare function splitmix32(seed: number): () => number;
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* `sfc32` (Small Fast Counter, 32-bit, 128-bit state) — the deterministic, non-cryptographic PRNG that
|
|
277
|
+
* drives every value `@cosyte/synth` generates. Chosen over `mulberry32` (whose author flags that it
|
|
278
|
+
* skips ~1/3 of 32-bit outputs) and over a CSPRNG (`node:crypto`, which is **not seedable** and would
|
|
279
|
+
* defeat reproducibility). A synthetic-fixture generator has **no secrets** — statistical quality plus
|
|
280
|
+
* byte-for-byte reproducibility is exactly the right trade.
|
|
281
|
+
*
|
|
282
|
+
* The state is four 32-bit words. This module exposes the raw step function; {@link ../rng/rng.Rng}
|
|
283
|
+
* wraps it with a seed-expansion ({@link ./splitmix32.splitmix32}) and the ergonomic draw helpers.
|
|
284
|
+
*
|
|
285
|
+
* @module
|
|
286
|
+
*/
|
|
287
|
+
/**
|
|
288
|
+
* The mutable four-word `sfc32` state. Threaded explicitly (never global) by {@link ../rng/rng.Rng}.
|
|
289
|
+
*/
|
|
290
|
+
interface Sfc32State {
|
|
291
|
+
/** State word `a`. */
|
|
292
|
+
a: number;
|
|
293
|
+
/** State word `b`. */
|
|
294
|
+
b: number;
|
|
295
|
+
/** State word `c`. */
|
|
296
|
+
c: number;
|
|
297
|
+
/** Counter word `d`. */
|
|
298
|
+
d: number;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Advance an {@link Sfc32State} in place by one step and return the next unsigned 32-bit integer.
|
|
302
|
+
*
|
|
303
|
+
* This is the canonical `sfc32` step. The state object is mutated (the counter `d` increments and the
|
|
304
|
+
* mixing words rotate); callers that need reproducible independence hold their own state and never
|
|
305
|
+
* share it — {@link ../rng/rng.Rng} creates a fresh state per seed so two runs from the same seed are
|
|
306
|
+
* identical.
|
|
307
|
+
*
|
|
308
|
+
* @param s - The state to advance. Mutated in place.
|
|
309
|
+
* @returns The next `uint32` in the stream.
|
|
310
|
+
* @example
|
|
311
|
+
* ```ts
|
|
312
|
+
* import { sfc32Next, type Sfc32State } from "@cosyte/synth";
|
|
313
|
+
* const s: Sfc32State = { a: 1, b: 2, c: 3, d: 4 };
|
|
314
|
+
* const x = sfc32Next(s); // uint32
|
|
315
|
+
* ```
|
|
316
|
+
*/
|
|
317
|
+
declare function sfc32Next(s: Sfc32State): number;
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Stable diagnostic codes for `@cosyte/synth` and the {@link SynthError} they travel on.
|
|
321
|
+
*
|
|
322
|
+
* Unlike a parser (which recovers from bad *input* into Tier-2 warnings), a **generator** has no input
|
|
323
|
+
* to tolerate — its reflex is *synthetic-by-construction* and *fail-closed on impossibility*. So the
|
|
324
|
+
* codes here are **fatal**: a caller asked for something the library cannot honor spec-clean, and the
|
|
325
|
+
* only safe answer is to throw, never to silently fabricate a value or a byte workaround. Codes are `key ===
|
|
326
|
+
* value` and part of the public contract —
|
|
327
|
+
* renaming one is a breaking change.
|
|
328
|
+
*
|
|
329
|
+
* @module
|
|
330
|
+
*/
|
|
331
|
+
/**
|
|
332
|
+
* The stable **fatal** code registry. Additions-only thereafter.
|
|
333
|
+
*
|
|
334
|
+
* @example
|
|
335
|
+
* ```ts
|
|
336
|
+
* import { SYNTH_FATAL_CODES, SynthError } from "@cosyte/synth";
|
|
337
|
+
* try {
|
|
338
|
+
* // ...generate...
|
|
339
|
+
* } catch (err) {
|
|
340
|
+
* if (err instanceof SynthError && err.code === SYNTH_FATAL_CODES.SYNTH_UNSUPPORTED_FORMAT) {
|
|
341
|
+
* // handle an unsupported format request
|
|
342
|
+
* }
|
|
343
|
+
* }
|
|
344
|
+
* ```
|
|
345
|
+
*/
|
|
346
|
+
declare const SYNTH_FATAL_CODES: {
|
|
347
|
+
/**
|
|
348
|
+
* A format was requested that this build cannot generate through a real parser builder/serializer
|
|
349
|
+
* (e.g. ASTM before `@cosyte/astm`'s serializer ships). Fatal — never a hand-written byte fallback.
|
|
350
|
+
*/
|
|
351
|
+
readonly SYNTH_UNSUPPORTED_FORMAT: "SYNTH_UNSUPPORTED_FORMAT";
|
|
352
|
+
/**
|
|
353
|
+
* A vendor quirk was requested that the target format's profile system does not support. Fatal —
|
|
354
|
+
* never a silent no-op and never a fabricated quirk.
|
|
355
|
+
*/
|
|
356
|
+
readonly SYNTH_UNSUPPORTED_QUIRK: "SYNTH_UNSUPPORTED_QUIRK";
|
|
357
|
+
};
|
|
358
|
+
/**
|
|
359
|
+
* A value from {@link SYNTH_FATAL_CODES} — the type carried by a thrown {@link SynthError}.
|
|
360
|
+
*/
|
|
361
|
+
type SynthFatalCode = (typeof SYNTH_FATAL_CODES)[keyof typeof SYNTH_FATAL_CODES];
|
|
362
|
+
/**
|
|
363
|
+
* The typed error every fatal `@cosyte/synth` condition throws. Carries a stable
|
|
364
|
+
* {@link SynthFatalCode} so callers branch on `err.code` without matching message text.
|
|
365
|
+
*
|
|
366
|
+
* @example
|
|
367
|
+
* ```ts
|
|
368
|
+
* import { SynthError, SYNTH_FATAL_CODES } from "@cosyte/synth";
|
|
369
|
+
* throw new SynthError(SYNTH_FATAL_CODES.SYNTH_UNSUPPORTED_FORMAT, "astm is not yet generable");
|
|
370
|
+
* ```
|
|
371
|
+
*/
|
|
372
|
+
declare class SynthError extends Error {
|
|
373
|
+
/** The stable fatal code. */
|
|
374
|
+
readonly code: SynthFatalCode;
|
|
375
|
+
/**
|
|
376
|
+
* @param code - The stable {@link SynthFatalCode}.
|
|
377
|
+
* @param message - A human-readable detail (never contains PHI — there is none).
|
|
378
|
+
*/
|
|
379
|
+
constructor(code: SynthFatalCode, message: string);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* `@cosyte/synth` — a deterministic, seedable **synthetic-data / test-fixture generator** for the
|
|
384
|
+
* cosyte healthcare formats. A *consumer* of the parsers, not a parser: it builds artifacts **through
|
|
385
|
+
* each parser's own builder/serializer** (so output is spec-clean by construction) and draws every
|
|
386
|
+
* value from a **guaranteed-non-colliding synthetic source** (so no output can be real or
|
|
387
|
+
* plausibly-real PHI). It is a **format/conformance generator, not a clinical simulator**.
|
|
388
|
+
*
|
|
389
|
+
* This root entry point exposes the **format-agnostic core**: the seeded PRNG, the synthetic-safety
|
|
390
|
+
* providers, the `Corpus` abstraction, the profile skeleton, and the fatal codes. Per-format
|
|
391
|
+
* generation lives behind its own subpath (`@cosyte/synth/hl7`) so importing the root never pulls a
|
|
392
|
+
* parser — the lazy per-format boundary.
|
|
393
|
+
*
|
|
394
|
+
* @module
|
|
395
|
+
*/
|
|
396
|
+
/**
|
|
397
|
+
* Library version string, synced with `package.json#version` by downstream release tooling.
|
|
398
|
+
*
|
|
399
|
+
* @example
|
|
400
|
+
* ```ts
|
|
401
|
+
* import { VERSION } from "@cosyte/synth";
|
|
402
|
+
* console.log(VERSION);
|
|
403
|
+
* ```
|
|
404
|
+
*/
|
|
405
|
+
declare const VERSION = "0.0.0";
|
|
406
|
+
|
|
407
|
+
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, 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, safe, sfc32Next, splitmix32, ssn, uuid };
|