Context
VerifyResult currently includes domain (the extracted domain) but not the original input string. For single verify() calls this is fine — the caller knows what they passed in. But for verifyBatch(), the only way to correlate results back to inputs is by array index:
const emails = ['alice@gmail.com', 'bob@yopmail.com', 'carol@gmail.com'];
const results = await guard.verifyBatch(emails);
// results[0].domain === 'gmail.com' — but was that alice or carol?
// You have to trust that results[0] maps to emails[0]
The domain field is lossy — it strips the local part. If two inputs share a domain, the results are indistinguishable without index tracking.
Proposed change
Add a query field to VerifyResult — the original email or domain that was verified:
interface VerifyResult {
query: string; // the original email or domain passed to verify()
isMatch: boolean;
domain: string | null;
matchedOn: string | null; // will become string[] per #3
isAllowlisted: boolean;
}
Example
const results = await guard.verifyBatch([
'alice@gmail.com',
'bob@yopmail.com',
'carol+test@gmail.com'
]);
// results[0]:
// {
// query: 'alice@gmail.com',
// isMatch: false,
// domain: 'gmail.com',
// ...
// }
// results[2]:
// {
// query: 'carol+test@gmail.com',
// isMatch: false,
// domain: 'gmail.com',
// ...
// }
Now each result is self-contained — no index tracking needed. Consumers can safely filter(), sort(), or reduce() the results array without losing context.
Why query?
It's the standard term for "the thing you asked us to look up." It pairs naturally with the verify concept: you queried alice@gmail.com, here's what we found. Alternatives considered:
input — too generic, sounds like a form field
email — inaccurate, we also accept bare domains
address — implies email specifically
original — sounds like a copy/transform context
Impact on other methods
verify() — also returns query for consistency, even though the caller already knows it
verifyBatch() — each result carries its own query
filter() — FilterResult.matched and FilterResult.clean already contain the original strings, so no change needed there
EnrichedVerifyResult — inherits query from VerifyResult
Acceptance criteria
Priority: 🔴 High — usability issue for batch operations
Context
VerifyResultcurrently includesdomain(the extracted domain) but not the original input string. For singleverify()calls this is fine — the caller knows what they passed in. But forverifyBatch(), the only way to correlate results back to inputs is by array index:The
domainfield is lossy — it strips the local part. If two inputs share a domain, the results are indistinguishable without index tracking.Proposed change
Add a
queryfield toVerifyResult— the original email or domain that was verified:Example
Now each result is self-contained — no index tracking needed. Consumers can safely
filter(),sort(), orreduce()the results array without losing context.Why
query?It's the standard term for "the thing you asked us to look up." It pairs naturally with the verify concept: you queried
alice@gmail.com, here's what we found. Alternatives considered:input— too generic, sounds like a form fieldemail— inaccurate, we also accept bare domainsaddress— implies email specificallyoriginal— sounds like a copy/transform contextImpact on other methods
verify()— also returnsqueryfor consistency, even though the caller already knows itverifyBatch()— each result carries its own queryfilter()—FilterResult.matchedandFilterResult.cleanalready contain the original strings, so no change needed thereEnrichedVerifyResult— inheritsqueryfromVerifyResultAcceptance criteria
queryfield added toVerifyResultverify()populatesquerywith the original argumentverifyBatch()results each carry their corresponding queryqueryis present and correct in single and batch callsPriority: 🔴 High — usability issue for batch operations