Skip to content

feat: include original query in VerifyResult #16

Description

@mdesoto

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

  • query field added to VerifyResult
  • verify() populates query with the original argument
  • verifyBatch() results each carry their corresponding query
  • Tests verifying query is present and correct in single and batch calls
  • README API reference updated

Priority: 🔴 High — usability issue for batch operations

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions