Skip to content

feat: add generate() to structural validators#68

Merged
jan-kubica merged 2 commits intomainfrom
feat/generate-structural
Mar 22, 2026
Merged

feat: add generate() to structural validators#68
jan-kubica merged 2 commits intomainfrom
feat/generate-structural

Conversation

@jan-kubica
Copy link
Copy Markdown
Contributor

@jan-kubica jan-kubica commented Mar 22, 2026

Summary

  • Add generate() functions to 27 structural (no-checksum) validators
  • Each generator produces random values that pass the corresponding validate() function
  • Added to: AD NRT, AI TIN, AL NIPT, AM TIN, AR DNI, AT Firmenbuchnummer, BD NID, BIC, CR CPF, DE Handelsreg, DE StNr, EG TN, GB NINO, GE PIN, IN PAN, IQ NID, IS VSK, KR BRN, LI PEID, MU BRN, NG NIN, NL KvK, PH PhilID, PK CNIC, US EIN, US ITIN, US SSN

Test plan

  • All existing tests pass (bun test)
  • Existing "examples are all valid" tests cover generate() indirectly

Open with Devin

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Mar 22, 2026

Greptile Summary

This PR adds generate() functions to 27 structural (checksum-free) validators, creating a consistent contract where validate(generate()) always returns { valid: true }. The generators are well-structured, make good use of the shared randomInt/randomDigits helpers, and correctly implement the more nuanced validators (e.g. SSN blacklist retry loop, NINO invalid-prefix rejection, KR BRN component constraints, ITIN allowed-group filtering).

Key observations:

  • All generators were verified to produce values that satisfy their corresponding validate() logic.
  • The US SSN and GB NINO generators properly handle rejection/retry loops for invalid values.
  • src/ai/tin.ts uses Math.random() < 0.5 for prefix selection instead of the randomInt helper used by every other generator in this PR.
  • src/ad/nrt.ts silently omits valid NRT prefixes "A", "F", and "L" (which have digit-range constraints); all generated values are still structurally valid but the omission is undocumented.
  • src/bic.ts hardcodes only 7 country codes while the validator accepts any [A-Z]{2} code, unnecessarily limiting generated value diversity.

Confidence Score: 4/5

  • Safe to merge — all generators produce values that pass their validators; remaining issues are style/consistency concerns only.
  • The core contract (validate(generate()) === valid) holds across all 27 generators after careful review. Previously raised issues (SSN blacklist guard, EIN/Handelsreg randomInt consistency) have been addressed. Remaining gaps are cosmetic: one generator uses Math.random() instead of randomInt, one silently skips valid prefixes without a comment, and the BIC generator has an unnecessarily narrow country-code pool. None of these are runtime correctness issues.
  • src/ai/tin.ts (Math.random inconsistency), src/ad/nrt.ts (undocumented prefix omission), src/bic.ts (hardcoded country list)

Important Files Changed

Filename Overview
src/ad/nrt.ts Generator is correct but silently omits valid prefixes "A", "F", "L" which have digit-range constraints; all generated values still pass validate().
src/ai/tin.ts Uses Math.random() < 0.5 for prefix selection instead of the randomInt helper used consistently across all other generators in this PR.
src/bic.ts Generator hardcodes only 7 country codes despite the validator accepting any [A-Z]{2} code; limits diversity of generated test values.
src/us/ssn.ts Generator correctly avoids area "000", "666", 900–999, group "00", serial "0000", and all three blacklisted SSNs via the outer for(;;) loop.
src/us/itin.ts Generator correctly constrains area to start with "9" and group to 70–99 excluding 89 and 93, matching the validator exactly.
src/gb/nino.ts Generator correctly rejects both invalid first/second letter sets and invalid two-letter prefixes via a do-while loop; format and suffix are correct.
src/kr/brn.ts Generator correctly enforces all three validator constraints: office ≥ 101, bizType ≠ "00", serial ≠ "0000".
src/in/pan.ts Generator correctly selects holder type from the same HOLDER_TYPES string used by the validator and produces a 10-character value matching PAN_RE.
src/pk/cnic.ts Generator correctly produces 13 digits with province from VALID_PROVINCES (1–7) and gender digit from 1–9, satisfying all validator constraints.
src/us/ein.ts Generator uses a comprehensive hardcoded list of valid EIN prefixes and consistently uses randomInt for selection.

Sequence Diagram

sequenceDiagram
    participant Caller
    participant generate
    participant validate

    Caller->>generate: generate()
    activate generate
    generate->>generate: randomInt / randomDigits
    generate-->>Caller: structurally valid string
    deactivate generate

    Caller->>validate: validate(generated)
    activate validate
    validate->>validate: compact()
    validate->>validate: length / format checks
    validate->>validate: component checks (RMO, prefix, group…)
    validate-->>Caller: { valid: true, compact: … }
    deactivate validate

    note over generate,validate: Contract: validate(generate()) must always return valid: true
Loading

Reviews (2): Last reviewed commit: "fix: address review comments" | Re-trigger Greptile

greptile-apps[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

- us/itin: use randomInt instead of Math.random for
  group selection (was causing unused import)
- us/ssn: add blacklist check in generate() loop to
  prevent producing known-invalid SSNs; drop unused
  randomDigits import
- de/handelsreg, us/ein: use randomInt for array
  selection, consistent with all other generators
@jan-kubica
Copy link
Copy Markdown
Contributor Author

All items addressed in b9d7037:

  1. ITIN unused import: Fixed — replaced Math.random with randomInt for group selection.
  2. SSN blacklist gap: Fixed — added BLACKLIST check in generate loop; dropped unused randomDigits import.
  3. Math.random inconsistency: Fixed — handelsreg and ein now use randomInt for array selection, consistent with all other generators.

CC on behalf of @jan-kubica

Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 new potential issues.

View 6 additional findings in Devin Review.

Open in Devin Review

Comment thread src/de/handelsreg.ts
Comment thread src/de/handelsreg.ts
Comment thread src/ad/nrt.ts
Comment thread src/bic.ts
@jan-kubica jan-kubica merged commit c393d32 into main Mar 22, 2026
5 of 6 checks passed
@jan-kubica jan-kubica deleted the feat/generate-structural branch March 22, 2026 19:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant