@visulima/disposable-email-domains 1.0.0-alpha.16 → 1.0.0-alpha.18

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 CHANGED
@@ -1,3 +1,42 @@
1
+ ## @visulima/disposable-email-domains [1.0.0-alpha.18](https://github.com/visulima/visulima/compare/@visulima/disposable-email-domains@1.0.0-alpha.17...@visulima/disposable-email-domains@1.0.0-alpha.18) (2026-06-30)
2
+
3
+ ### Bug Fixes
4
+
5
+ * **disposable-email-domains:** emit `export =` for /domains types ([b80fd58](https://github.com/visulima/visulima/commit/b80fd587995e376f9cb6d872e387b5fc2d96e6d1))
6
+
7
+ ### Styles
8
+
9
+ * cs fixes ([2a960bb](https://github.com/visulima/visulima/commit/2a960bb1772c9dc70080e2d75d3a0d827034e294))
10
+
11
+ ### Miscellaneous Chores
12
+
13
+ * add fallow code-intelligence across all packages ([a3b4821](https://github.com/visulima/visulima/commit/a3b48215002e86fed20f2973038b5d4a0aa1ce04))
14
+
15
+ ### Continuous Integration
16
+
17
+ * **fallow:** make fallow:health advisory (--report-only) ([d57148e](https://github.com/visulima/visulima/commit/d57148ea0e3556b4c24d8d336b9fa14987f5dc7d))
18
+ * **lint:** raise eslint job timeout and cache slow per-package eslint runs ([#717](https://github.com/visulima/visulima/issues/717)) ([c93878d](https://github.com/visulima/visulima/commit/c93878dbfa1888cc834704448ae6eefd3098597e)), closes [#713](https://github.com/visulima/visulima/issues/713)
19
+
20
+ ## @visulima/disposable-email-domains [1.0.0-alpha.17](https://github.com/visulima/visulima/compare/@visulima/disposable-email-domains@1.0.0-alpha.16...@visulima/disposable-email-domains@1.0.0-alpha.17) (2026-06-13)
21
+
22
+ ### Features
23
+
24
+ * **disposable-email-domains:** add edge support, allowlist, bare-domain api to disposable check ([a3d1d95](https://github.com/visulima/visulima/commit/a3d1d9551cf857d0c11d245e7126cde73a302fd7))
25
+
26
+ ### Documentation
27
+
28
+ * **disposable-email-domains:** refresh benchmark timings in README ([5ea04f7](https://github.com/visulima/visulima/commit/5ea04f75479bffe2bceee8d0e9f72285734dcbbf))
29
+ * regenerate package tables ([287ded9](https://github.com/visulima/visulima/commit/287ded982f6d4bcbc3401020732302ebde170933))
30
+
31
+ ### Build System
32
+
33
+ * **deps:** update disposable-email-domains dependencies ([77c2d3b](https://github.com/visulima/visulima/commit/77c2d3b862ab792a574c95de25effaf58d739c72))
34
+
35
+
36
+ ### Dependencies
37
+
38
+ * **@visulima/tabular:** upgraded to 4.0.0-alpha.14
39
+
1
40
  ## @visulima/disposable-email-domains [1.0.0-alpha.16](https://github.com/visulima/visulima/compare/@visulima/disposable-email-domains@1.0.0-alpha.15...@visulima/disposable-email-domains@1.0.0-alpha.16) (2026-06-04)
2
41
 
3
42
  ### Bug Fixes
package/README.md CHANGED
@@ -54,27 +54,27 @@ pnpm add @visulima/disposable-email-domains
54
54
 
55
55
  | Repository | Domains | Success | Performance |
56
56
  |------------|---------|---------|-------------|
57
- | kslr/disposable-email-domains | 120,210 | ✅ | 1.03s (1.8 MB) |
58
- | disposable/disposable-email-domains | 72,543 | ✅ | 0.59s (1.1 MB) |
59
- | FGRibreau/mailchecker | 56,048 | ✅ | 0.60s (840.7 KB) |
60
- | wesbos/burner-email-providers | 27,283 | ✅ | 0.07s (388.1 KB) |
61
- | groundcat/disposable-email-domain-list | 23,767 | ✅ | 0.12s (332.9 KB) |
62
- | sublime-security/static-files | 10,523 | ✅ | 0.37s (144.0 KB) |
63
- | 7c/fakefilter | 9,792 | ✅ | 0.07s (135.9 KB) |
64
- | disposable-email-domains/disposable-email-domains | 5,739 | ✅ | 0.12s (73.0 KB) |
65
- | willwhite/freemail | 4,462 | ✅ | 0.13s (61.8 KB) |
66
- | eser/sanitizer-svc | 3,855 | ✅ | 0.12s (48.9 KB) |
67
- | unkn0w/disposable-email-domain-list | 3,617 | ✅ | 0.20s (45.8 KB) |
68
- | MattKetmo/EmailChecker | 2,515 | ✅ | 0.20s (32.4 KB) |
69
- | GeroldSetz/emailondeck.com-domains | 1,121 | ✅ | 0.09s (15.4 KB) |
70
- | castle/disposable-email-domains | 1,000 | ✅ | 0.33s (12.9 KB) |
71
- | jespernissen/disposable-maildomain-list | 994 | ✅ | 0.06s (12.8 KB) |
72
- | TheDahoom/disposable-email | 18 | ✅ | 0.11s (234 B) |
57
+ | kslr/disposable-email-domains | 123,343 | ✅ | 1.18s (1.8 MB) |
58
+ | disposable/disposable-email-domains | 74,328 | ✅ | 0.50s (1.1 MB) |
59
+ | FGRibreau/mailchecker | 56,360 | ✅ | 0.45s (846.7 KB) |
60
+ | wesbos/burner-email-providers | 27,279 | ✅ | 0.45s (388.1 KB) |
61
+ | groundcat/disposable-email-domain-list | 17,012 | ✅ | 0.55s (240.3 KB) |
62
+ | sublime-security/static-files | 10,522 | ✅ | 0.17s (144.0 KB) |
63
+ | 7c/fakefilter | 10,151 | ✅ | 0.32s (140.8 KB) |
64
+ | disposable-email-domains/disposable-email-domains | 7,860 | ✅ | 0.21s (109.1 KB) |
65
+ | willwhite/freemail | 4,462 | ✅ | 0.21s (61.8 KB) |
66
+ | eser/sanitizer-svc | 3,855 | ✅ | 0.23s (48.9 KB) |
67
+ | unkn0w/disposable-email-domain-list | 3,618 | ✅ | 0.08s (45.8 KB) |
68
+ | MattKetmo/EmailChecker | 2,515 | ✅ | 0.14s (32.4 KB) |
69
+ | GeroldSetz/emailondeck.com-domains | 1,121 | ✅ | 0.22s (15.4 KB) |
70
+ | castle/disposable-email-domains | 1,000 | ✅ | 0.12s (13.4 KB) |
71
+ | jespernissen/disposable-maildomain-list | 993 | ✅ | 0.10s (12.8 KB) |
72
+ | TheDahoom/disposable-email | 18 | ✅ | 0.22s (234 B) |
73
73
 
74
74
  <!-- END_PLACEHOLDER_CONTRIBUTING -->
75
75
  <!-- START_PLACEHOLDER_LAST_UPDATED -->
76
76
 
77
- _Last updated: 2026-06-04_
77
+ _Last updated: 2026-06-30_
78
78
 
79
79
  <!-- END_PLACEHOLDER_LAST_UPDATED -->
80
80
 
@@ -99,86 +99,172 @@ results.forEach((isDisposable, email) => {
99
99
  });
100
100
  ```
101
101
 
102
- ### Whitelist Protection
102
+ ### Provider whitelist (baked into the list)
103
103
 
104
- This package automatically whitelists common email providers (like Gmail, Yahoo, Outlook, etc.) from the [email-providers](https://github.com/derhuerst/email-providers) package. This ensures that legitimate email providers are never incorrectly flagged as disposable, even if they appear in the disposable domains list.
104
+ Common email providers (Gmail, Yahoo, Outlook, etc.) from the [email-providers](https://github.com/derhuerst/email-providers) package are filtered **at list-generation time** — they are removed from the published `domains.json` before it ships, so they can never be flagged as disposable. This is _not_ a runtime allowlist: there is no provider-whitelist parameter at call time. If you need a runtime escape hatch for a specific domain, use the `allowDomains` option below.
105
105
 
106
106
  ```typescript
107
107
  import { isDisposableEmail } from "@visulima/disposable-email-domains";
108
108
 
109
- // Common email providers are automatically whitelisted
110
- isDisposableEmail("user@gmail.com"); // false - whitelisted
111
- isDisposableEmail("user@yahoo.com"); // false - whitelisted
112
- isDisposableEmail("user@outlook.com"); // false - whitelisted
109
+ // Common providers are absent from the list, so they are never flagged
110
+ isDisposableEmail("user@gmail.com"); // false
111
+ isDisposableEmail("user@yahoo.com"); // false
112
+ isDisposableEmail("user@outlook.com"); // false
113
113
 
114
114
  // Disposable emails are still detected
115
115
  isDisposableEmail("user@mailinator.com"); // true - disposable
116
116
  ```
117
117
 
118
- ### Custom Domains
118
+ ### Custom domains
119
119
 
120
- You can provide custom disposable domains to check against:
120
+ You can provide custom disposable domains to check on top of the built-in list. Custom domains use the same wildcard/subdomain semantics as the built-in list (a custom `custom-disposable.com` also matches `sub.custom-disposable.com`):
121
121
 
122
122
  ```typescript
123
123
  import { isDisposableEmail, areDisposableEmails } from "@visulima/disposable-email-domains";
124
124
 
125
125
  const customDomains = new Set(["custom-disposable.com", "temp-mail.org"]);
126
126
 
127
- // Check with custom domains
127
+ // Legacy form: pass a Set directly
128
128
  if (isDisposableEmail("user@custom-disposable.com", customDomains)) {
129
129
  console.log("Custom disposable email detected!");
130
130
  }
131
131
 
132
+ // Options-object form (equivalent)
133
+ isDisposableEmail("user@custom-disposable.com", { customDomains });
134
+
132
135
  // Batch check with custom domains
133
- const emails = ["user@custom-disposable.com", "user@example.com"];
134
- const results = areDisposableEmails(emails, customDomains);
136
+ const results = areDisposableEmails(["user@custom-disposable.com", "user@example.com"], customDomains);
137
+ ```
135
138
 
136
- results.forEach((isDisposable, email) => {
137
- console.log(`${email}: ${isDisposable ? "disposable" : "valid"}`);
138
- });
139
+ ### Runtime allowlist (`allowDomains`)
140
+
141
+ If a legitimate customer domain wrongly ends up in the list, allowlist it at runtime without forking. The allowlist is checked **before** the disposable list and wins over both the built-in list and `customDomains`. It also honours subdomain matching:
142
+
143
+ ```typescript
144
+ import { isDisposableEmail } from "@visulima/disposable-email-domains";
145
+
146
+ const allowDomains = new Set(["legit-customer.com"]);
147
+
148
+ isDisposableEmail("user@legit-customer.com", { allowDomains }); // false, even if it's in the list
149
+ isDisposableEmail("user@mail.legit-customer.com", { allowDomains }); // false (subdomain)
150
+ ```
151
+
152
+ ### Bare-domain checks
153
+
154
+ If you already have a domain (e.g. from an MX lookup or a parsed signup form), use `isDisposableDomain` / `extractDomain` directly instead of fabricating an `x@domain` address:
155
+
156
+ ```typescript
157
+ import { isDisposableDomain, extractDomain } from "@visulima/disposable-email-domains";
158
+
159
+ isDisposableDomain("mailinator.com"); // true
160
+ extractDomain("User@Example.COM"); // "example.com"
161
+ ```
162
+
163
+ ### Edge / browser / bundled runtimes
164
+
165
+ By default the package reads `dist/domains.json` from disk via `node:fs`. That does not work in Cloudflare Workers, Next.js middleware/edge, Deno, or bundles that relocate `index.js` away from the data file. For those environments, import the list statically and inject it once at startup with `setDomains`:
166
+
167
+ ```typescript
168
+ import { setDomains, isDisposableEmail } from "@visulima/disposable-email-domains";
169
+ import domains from "@visulima/disposable-email-domains/domains" with { type: "json" };
170
+
171
+ setDomains(domains);
172
+
173
+ isDisposableEmail("user@mailinator.com"); // true — no filesystem access
174
+ ```
175
+
176
+ On Node you can also call `await preload()` once at startup to move the synchronous read+parse of the multi-megabyte list off the request hot path, and `isListLoaded()` to detect the degraded fail-open state (e.g. a missing/corrupt data file):
177
+
178
+ ```typescript
179
+ import { preload, isListLoaded } from "@visulima/disposable-email-domains";
180
+
181
+ await preload();
182
+
183
+ if (!isListLoaded()) {
184
+ // The built-in list failed to load — disposable detection is disabled.
185
+ }
186
+ ```
187
+
188
+ ### Raw domain list (`./domains`)
189
+
190
+ The raw, sorted array of disposable domains is exported from the `./domains` subpath. In Node ESM you must use a JSON import attribute:
191
+
192
+ ```typescript
193
+ import domains from "@visulima/disposable-email-domains/domains" with { type: "json" };
194
+
195
+ console.log(domains.length); // number of disposable domains
139
196
  ```
140
197
 
141
198
  ## API Reference
142
199
 
143
200
  ### Functions
144
201
 
145
- #### `isDisposableEmail(email, customDomains?)`
202
+ All check functions accept either a `Set<string>` of additional disposable domains (legacy) or an options object:
203
+
204
+ ```typescript
205
+ interface DisposableEmailOptions {
206
+ /** Domains that should never be treated as disposable (wins over everything, supports subdomains). */
207
+ allowDomains?: Set<string>;
208
+ /** Extra disposable domains to check on top of the built-in list (supports subdomains). */
209
+ customDomains?: Set<string>;
210
+ }
211
+ ```
146
212
 
147
- Checks if an email address is from a disposable email service. Common email providers (Gmail, Yahoo, Outlook, etc.) are automatically whitelisted and will never be flagged as disposable.
213
+ #### `isDisposableEmail(email, options?)`
214
+
215
+ Checks if an email address is from a disposable email service.
148
216
 
149
217
  - **Parameters:**
150
218
  - `email` (string): The email address to check
151
- - `customDomains?` (Set<string>): Optional set of additional disposable domains to check
152
- - **Returns:** `boolean` - True if the email is from a disposable domain
219
+ - `options?` (`Set<string>` | `DisposableEmailOptions`): A set of additional disposable domains, or an options object
220
+ - **Returns:** `boolean` — True if the email is from a disposable domain
153
221
  - **Features:**
154
222
  - Case-insensitive matching
155
- - Supports wildcard matching (e.g., `subdomain.33mail.com` matches `33mail.com`)
156
- - Automatically whitelists common email providers
223
+ - Wildcard/subdomain matching (e.g., `subdomain.33mail.com` matches `33mail.com`) for built-in, custom, and allowlisted domains
157
224
 
158
- #### `areDisposableEmails(emails, customDomains?)`
225
+ #### `areDisposableEmails(emails, options?)`
159
226
 
160
227
  Checks multiple email addresses at once. Returns a Map for efficient lookups.
161
228
 
162
229
  - **Parameters:**
163
230
  - `emails` (string[]): Array of email addresses to check
164
- - `customDomains?` (Set<string>): Optional set of additional disposable domains to check
165
- - **Returns:** `Map<string, boolean>` - Map of email to boolean indicating if it's disposable
166
- - **Features:**
167
- - Batch processing for better performance
168
- - Same whitelist protection as `isDisposableEmail`
231
+ - `options?` (`Set<string>` | `DisposableEmailOptions`): A set of additional disposable domains, or an options object
232
+ - **Returns:** `Map<string, boolean>` — Map of email to boolean indicating if it's disposable
233
+
234
+ #### `isDisposableDomain(domain, options?)`
235
+
236
+ Like `isDisposableEmail` but accepts a bare domain rather than a full email address.
237
+
238
+ #### `extractDomain(email)`
239
+
240
+ Returns the normalized (lowercased, trimmed) domain of an email address, or `undefined` if the address is invalid.
241
+
242
+ #### `setDomains(domains)`
243
+
244
+ Injects the disposable-domain list explicitly, bypassing the Node filesystem loader. Use in edge/browser/bundled runtimes (see [Edge / browser / bundled runtimes](#edge--browser--bundled-runtimes)).
245
+
246
+ #### `preload()`
247
+
248
+ Eagerly loads the built-in list (Node) so the first check does not stall the event loop. Returns a `Promise<void>`.
249
+
250
+ #### `isListLoaded()`
251
+
252
+ Returns `true` once the built-in list is loaded; `false` if it has not been accessed yet or failed to load (missing/corrupt data file). Useful to detect the degraded fail-open state.
169
253
 
170
254
  ### How It Works
171
255
 
172
256
  1. **Domain List**: The package maintains a regularly updated list of disposable email domains from multiple trusted sources (see Contributing Sources above).
173
257
 
174
- 2. **Whitelist Protection**: Common email providers from the [email-providers](https://github.com/derhuerst/email-providers) package are automatically whitelisted. This ensures legitimate providers like Gmail, Yahoo, and Outlook are never incorrectly flagged as disposable.
258
+ 2. **Provider whitelist**: Common email providers from the [email-providers](https://github.com/derhuerst/email-providers) package are filtered out **when the list is generated**, so they are simply absent from the published list. There is no runtime provider-whitelist mechanism; use `allowDomains` for per-call exceptions.
175
259
 
176
260
  3. **Wildcard Matching**: The package supports wildcard matching by checking parent domains. For example, `subdomain.33mail.com` will match `33mail.com` if it's in the disposable list.
177
261
 
178
- 4. **Custom Domains**: You can provide additional disposable domains to check against, useful for domain-specific blocklists.
262
+ 4. **Custom & allow domains**: You can supply additional disposable domains (`customDomains`) or a runtime allowlist (`allowDomains`), both with subdomain matching.
179
263
 
180
264
  ## Related
181
265
 
266
+ - [@visulima/email](https://github.com/visulima/visulima/tree/main/packages/email/email) — multi-provider email library that re-exports this check at `@visulima/email/validation/disposable-email-domains`.
267
+
182
268
  ## Supported Node.js Versions
183
269
 
184
270
  Libraries in this ecosystem make the best effort to track [Node.js’ release schedule](https://github.com/nodejs/release#release-schedule).
@@ -0,0 +1,2 @@
1
+ declare const domains: string[];
2
+ export = domains;