{"_id":"@dcsv-io/d2-validation-abstractions","name":"@dcsv-io/d2-validation-abstractions","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.2":{"name":"@dcsv-io/d2-validation-abstractions","version":"0.1.2","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"dependencies":{"zod":"4.3.6","@dcsv-io/d2-result":"0.1.2","@dcsv-io/d2-geo-abstractions":"0.1.2"},"devDependencies":{"@vitest/coverage-v8":"4.0.18","typescript":"5.9.3","vitest":"4.0.18","@dcsv-io/d2-utilities":"0.1.2"},"scripts":{"build":"tsc -b","test":"vitest run","test:coverage":"vitest run --coverage","type-check:test":"tsc -p tsconfig.test.json"},"_id":"@dcsv-io/d2-validation-abstractions@0.1.2","description":"<!-- Copyright (c) DCSV. Licensed under the Apache License, Version 2.0. -->","_integrity":"sha512-aLJXVt6HTKkjO693wQWMtjvx9loirUd2cBrac/Elf9fCShhcyZbZ8siqBx+skc3W7NWopL2Pn5H5lxCvhpKAFw==","_resolved":"/home/runner/work/D2-Public/D2-Public/bundle/npm/dcsv-io-d2-validation-abstractions-0.1.2.tgz","_from":"file:bundle/npm/dcsv-io-d2-validation-abstractions-0.1.2.tgz","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-aLJXVt6HTKkjO693wQWMtjvx9loirUd2cBrac/Elf9fCShhcyZbZ8siqBx+skc3W7NWopL2Pn5H5lxCvhpKAFw==","shasum":"eb397e696b32fdfac8461cdd244dc53a0c07cd00","tarball":"https://registry.npmjs.org/@dcsv-io/d2-validation-abstractions/-/d2-validation-abstractions-0.1.2.tgz","fileCount":27,"unpackedSize":44598,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIGnQtb2CfU37iZGKf7mRp4PYvHhmtA1/XQ8kL8UiDvVDAiAFxf/3CXOgcFMFmM4//9TF9rtk9aww5XJ4ce8QjBvv7g=="}]},"_npmUser":{"name":"dcsv-tristan","email":"tristan@dcsv.io"},"directories":{},"maintainers":[{"name":"dcsv-tristan","email":"tristan@dcsv.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/d2-validation-abstractions_0.1.2_1784485145909_0.6773697034695787"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-19T18:19:05.777Z","0.1.2":"2026-07-19T18:19:06.049Z","modified":"2026-07-19T18:19:06.250Z"},"maintainers":[{"name":"dcsv-tristan","email":"tristan@dcsv.io"}],"description":"<!-- Copyright (c) DCSV. Licensed under the Apache License, Version 2.0. -->","readme":"<!--\nCopyright (c) DCSV. Licensed under the Apache License, Version 2.0.\n-->\n\n# @dcsv-io/d2-validation-abstractions\n\n> **Audience**: backend Node/TypeScript service and BFF engineers who need\n> the validator contract surface — email, phone, and postal-code validator\n> interfaces — or the shared field-constraints catalog (field-length bounds +\n> name/sex taxonomy enums) — without dragging in the default implementations\n> (`@dcsv-io/d2-validation`).\n\nHand-written validator contract interfaces **plus the codegen-emitted shared\nfield-constraints catalog** (field-length / digit-count constants + closed-list\ntaxonomy enums). Mirrors `DcsvIo.D2.Validation.Abstractions` (.NET).\n\n## Install\n\n```bash\npnpm add @dcsv-io/d2-validation-abstractions\n```\n\n## Overview\n\nThe validation layer ships in two TS packages:\n\n- **`@dcsv-io/d2-validation-abstractions`** — this package. The three validator\n contract interfaces (`IEmailValidator`, `IPhoneValidator`,\n `IPostalCodeValidator`) AND the codegen-emitted `FieldConstraints` bounds +\n `NamePrefix` / `NameSuffix` / `BiologicalSex` taxonomy enums (with Zod\n schemas). The interfaces are pure types (near-zero runtime payload); the\n emitted catalog carries the const objects + Zod schemas (a small `zod`\n runtime dependency).\n- **`@dcsv-io/d2-validation`** — the default implementations backed by the standard\n normalization rules. Depends on this package.\n\nDomain code that depends on a validator imports the interface from\n`@dcsv-io/d2-validation-abstractions`; only composition-root code wires the concrete\nimplementation from `@dcsv-io/d2-validation`. Code that needs the shared field bounds\nor taxonomy enums imports `FieldConstraints` / `NamePrefix` / etc. directly.\n\n## Field-constraints catalog (codegen-emitted)\n\nSpec-driven from `contracts/validation/field-constraints.spec.json` via\nGenerated from `contracts/validation/field-constraints.spec.json` — emitted into\n`src/generated/` (committed, `linguist-generated`). The same spec drives the\n.NET-side `DcsvIo.D2.Validation.Abstractions` catalog, so cross-language drift\nis structurally impossible.\n\n- **`FieldConstraints`** (`field-constraints.g.ts`) — a plain numeric\n `as const` object of the 16 field-length / digit-count bounds (matches geo's\n numeric `GeopoliticalEntityType` shape; the values are ints, not a closed-set\n wire vocabulary needing a brand) plus the derived `FieldConstraint` value\n type. Read these to gate Zod schemas / form validation against the same\n bounds the .NET `Create(...)` gates enforce.\n- **`NamePrefix` / `NameSuffix` / `BiologicalSex`** (`taxonomy.g.ts`) — for\n each closed-list enum: a string-valued `as const` object (member name IS the\n wire form), a branded derived type, a `z.enum([...])` schema (`*Schema`), and\n an `ALL_*_SET` `ReadonlySet<string>` membership set. The schemas gate BFF /\n client input against the same closed vocabularies the .NET enums encode.\n\nThe catalog carries no localized display strings (member names are\ndisplay-adequate); FE labels route through i18n `TK.*` keys if a picker needs\nthem.\n\n## Public surface\n\n| Export                          | Source file                                | Purpose                                                                                            |\n| ------------------------------- | ------------------------------------------ | -------------------------------------------------------------------------------------------------- |\n| `IEmailValidator` (interface)   | `src/interfaces/i-email-validator.ts`      | Validate an email; returns the normalized (trimmed + lowercased) address on success.               |\n| `IPhoneValidator` (interface)   | `src/interfaces/i-phone-validator.ts`      | Validate a phone number; returns the normalized E.164 form on success.                             |\n| `IPostalCodeValidator` (interface) | `src/interfaces/i-postal-code-validator.ts` | Country-aware postal-code validation; returns the normalized (trimmed + uppercased) code on success. |\n| `FieldConstraints` + `FieldConstraint` | `src/generated/field-constraints.g.ts` | Codegen-emitted numeric `as const` field-length / digit-count bounds + derived value type. |\n| `NamePrefix` / `NameSuffix` / `BiologicalSex` (+ `*Schema` + `ALL_*_SET`) | `src/generated/taxonomy.g.ts` | Codegen-emitted closed-list taxonomy enums: const object + branded type + Zod `z.enum` schema + membership set. |\n\n## Normalized return contract\n\nEvery validator exposes a single `validate(...)` method returning\n`D2Result<string>`:\n\n- **Success** — an `ok` `D2Result` whose data is the normalized value:\n - `IEmailValidator` → trimmed and lowercased email.\n - `IPhoneValidator` → E.164 representation.\n - `IPostalCodeValidator` → trimmed and uppercased postal code.\n- **Failure** — a `validationFailed` `D2Result` carrying a single per-field\n `InputError`. The field key is `\"email\"`, `\"phone\"`, or `\"postalCode\"`\n respectively. Failure covers `undefined`, empty, whitespace-only, and\n structurally invalid input.\n\nReturning the normalized value (rather than a bare boolean) lets callers\npersist the canonical form directly without a second normalization pass.\n\n## Parity with .NET\n\nMirrors `DcsvIo.D2.Validation.Abstractions`:\n\n- `IEmailValidator` ↔ `DcsvIo.D2.Validation.Abstractions.IEmailValidator`.\n- `IPhoneValidator` ↔ `DcsvIo.D2.Validation.Abstractions.IPhoneValidator`.\n- `IPostalCodeValidator` ↔\n `DcsvIo.D2.Validation.Abstractions.IPostalCodeValidator`.\n\nEach interface exposes the same single `validate(...)` method returning\n`D2Result<string>` with the same normalization semantics and the same\nper-field `InputError` field keys across both runtimes.\n\nOptional parameters use `undefined` (not `null`) per workspace TS\nconvention. `null` arriving from the .NET wire normalizes to `undefined` at\nthe deserialization boundary.\n\n## Dependencies\n\n- `@dcsv-io/d2-result` — `D2Result<string>` return type.\n- `@dcsv-io/d2-geo-abstractions` — `CountryCode` for the phone default-region and\n postal-code country parameters.\n- `zod` — the emitted taxonomy `*Schema` exports are `z.enum([...])` schemas\n (pinned to the same version `@dcsv-io/d2-geo-abstractions` uses). The validator\n interfaces themselves carry no runtime; the dependency is the catalog's.\n\n## Telemetry\n\nNo telemetry surface — foundation lib emits no spans or metrics. Consumers\ninstrument the validator call sites in their own OTel setup.\n\n## Configuration\n\nNo configuration — zero-config; the contracts carry no tunable behavior.\n","readmeFilename":"README.md","_rev":"1-cd39e6b72548b38358cb04804023fc2d"}