UNPKG

@eristack/person

Version:

Structured person name and gender identity — normalize and display, not HRIS

131 lines (127 loc) • 4.02 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { GENDER_IDENTITIES: () => GENDER_IDENTITIES, PERSON_PARSE_CODE: () => PERSON_PARSE_CODE, PersonParseError: () => PersonParseError, formatPersonDisplay: () => formatPersonDisplay, formatPersonSortable: () => formatPersonSortable, isGenderIdentity: () => isGenderIdentity, normalizeGenderIdentity: () => normalizeGenderIdentity, normalizePerson: () => normalizePerson, normalizePersonName: () => normalizePersonName }); module.exports = __toCommonJS(index_exports); // src/core/errors.ts var PERSON_PARSE_CODE = "PERSON_PARSE"; var PersonParseError = class extends Error { code = PERSON_PARSE_CODE; constructor(message) { super(message); this.name = "PersonParseError"; } }; // src/core/types.ts var GENDER_IDENTITIES = [ "unknown", "woman", "man", "non_binary", "prefer_not_to_say", "other" ]; // src/core/person.ts function trimOptional(value) { const t = value?.trim(); return t ? t : void 0; } function trimRequired(value, field) { const t = value.trim(); if (!t) { throw new PersonParseError(`${field} is required`); } return t; } function normalizePersonName(input) { return { given: trimRequired(input.given, "name.given"), family: trimRequired(input.family, "name.family"), middle: trimOptional(input.middle), prefix: trimOptional(input.prefix), suffix: trimOptional(input.suffix) }; } function isGenderIdentity(value) { return GENDER_IDENTITIES.includes(value); } function normalizeGenderIdentity(value) { const normalized = value.trim().toLowerCase().replace(/-/g, "_"); if (!isGenderIdentity(normalized)) { throw new PersonParseError(`Invalid gender identity "${value}"`); } return normalized; } function normalizePerson(input) { const name = normalizePersonName(input.name); const gender = input.gender ? normalizeGenderIdentity(input.gender) : void 0; const genderOther = trimOptional(input.genderOther); if (gender === "other" && !genderOther) { throw new PersonParseError("genderOther is required when gender is other"); } if (gender !== "other" && genderOther) { throw new PersonParseError("genderOther is only allowed when gender is other"); } return { name, gender, genderOther }; } function formatPersonDisplay(person, options = {}) { const p = normalizePerson(person); if (options.familyFirst) { return formatPersonSortable(p); } const parts = [ p.name.prefix, p.name.given, p.name.middle, p.name.family, p.name.suffix ].filter(Boolean); return parts.join(" "); } function formatPersonSortable(person) { const p = normalizePerson(person); const givenParts = [p.name.given, p.name.middle].filter(Boolean).join(" "); const family = p.name.family; const suffix = p.name.suffix ? ` ${p.name.suffix}` : ""; return `${family}${suffix}, ${givenParts}`; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { GENDER_IDENTITIES, PERSON_PARSE_CODE, PersonParseError, formatPersonDisplay, formatPersonSortable, isGenderIdentity, normalizeGenderIdentity, normalizePerson, normalizePersonName }); //# sourceMappingURL=index.cjs.map