UNPKG

nrb-qr-parser

Version:

Reads QR Code string from Malawi Registration National Bureau Identification document and converts it to a json format

253 lines (252 loc) 9.16 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseNrbQr = void 0; const util_1 = require("./util"); var Attribute; (function (Attribute) { Attribute["GIVEN_NAME"] = "given_name"; Attribute["FAMILY_NAME"] = "family_name"; Attribute["BIRTHDATE"] = "birthdate"; Attribute["GENDER"] = "gender"; Attribute["NATIONAL_ID"] = "identifier"; Attribute["REGISTRATION_DATE"] = "registration_date"; Attribute["REGISTRATION_TA"] = "registration_ta"; Attribute["REGISTRATION_DISTRICT"] = "registration_district"; Attribute["REGISTRATION_VILLAGE"] = "registration_village"; Attribute["MACHINE_READABLE_ZONE"] = "machine_readable_zone"; })(Attribute || (Attribute = {})); const SUPPORTED_DOCS = { '01': { type: "National registration receipt", model: [ [ Attribute.REGISTRATION_DISTRICT, (str) => str, (str) => (0, util_1.isGeneralString)(str), true ], [ Attribute.REGISTRATION_DATE, (str) => (0, util_1.formatDate)(str), (str) => (0, util_1.isDatePattern)(str), true ], [ Attribute.REGISTRATION_TA, (str) => str, (str) => (0, util_1.isGeneralString)(str), true ], [ Attribute.REGISTRATION_VILLAGE, (str) => str, (str) => (0, util_1.isGeneralString)(str), true ], [ Attribute.FAMILY_NAME, (str) => (0, util_1.toSentenceCase)(str), (str) => (0, util_1.isFullName)(str), true ], [ Attribute.GIVEN_NAME, (str) => (0, util_1.toSentenceCase)(str), (str) => (0, util_1.isFullName)(str), true ], [ Attribute.NATIONAL_ID, (str) => str, (str) => (0, util_1.isValidNationalID)(str) ], [ Attribute.GENDER, (str) => (0, util_1.formatGender)(str), (str) => (0, util_1.isGender)(str) ], [ Attribute.BIRTHDATE, (str) => (0, util_1.formatDate)(str), (str) => (0, util_1.isDatePattern)(str) ] ] }, '03': { type: 'Malawi National ID', model: [ [ Attribute.MACHINE_READABLE_ZONE, (str) => str, (str) => (0, util_1.isMachineReadableZone)(str), true ], [ Attribute.FAMILY_NAME, (str) => str, (str) => (0, util_1.isValidNationalIDName)(str), true ], [ Attribute.NATIONAL_ID, (str) => str, (str, dataMap) => { return (0, util_1.isValidNationalID)(str) && // Verify the value is actually a NationalID by checking the machine reable zone.. // These values need to Match! new RegExp(str).test(dataMap?.[Attribute.MACHINE_READABLE_ZONE]); }, true ], [ Attribute.GIVEN_NAME, (str) => { // For Given Names which appear as JOHN, NIXON const fmt1 = `${str}`.match(/(\w*),\s*\w+/i); if (fmt1 && fmt1.length) return fmt1[1]; // For GivenNames which appear as NIXONMale or YENSIFEMALE const fmt2 = `${str}`.match(/([A-Z][a-zA-Z'’-]+)(Male|Female)$/); if (fmt2 && fmt2.length) return fmt2[1]; return str; }, (str) => (0, util_1.isValidNationalIDName)(str) ], [ Attribute.GENDER, (str) => (0, util_1.formatGender)(str), (str) => (0, util_1.isGender)(str), true ], [ Attribute.BIRTHDATE, (str) => (0, util_1.formatDate)(str), (str) => (0, util_1.isDatePattern)(str), true ], [ Attribute.REGISTRATION_DATE, (str) => (0, util_1.formatDate)(str), (str) => (0, util_1.isDatePattern)(str), true ] ] }, '04': { type: 'Birth certificate', model: [ [ Attribute.NATIONAL_ID, (str) => str, (str) => (0, util_1.isValidNationalID)(str), true ], [ Attribute.GIVEN_NAME, (str) => (0, util_1.toSentenceCase)(str.split(' ')[0]), (str) => (0, util_1.isFullName)(str) ], [ Attribute.FAMILY_NAME, (str) => (0, util_1.toSentenceCase)(str.split(' ').reduce((_, c) => c, '')), (str) => (0, util_1.isFullName)(str), true ], [ Attribute.BIRTHDATE, (str) => (0, util_1.formatDate)(str), (str) => (0, util_1.isDatePattern)(str), true ], [ Attribute.GENDER, (str) => (0, util_1.formatGender)(str), (str) => (0, util_1.isGender)(str) ] ] }, '05': { type: 'Death certificate', model: [ [ Attribute.NATIONAL_ID, (str) => str, (str) => (0, util_1.isValidNationalID)(str), true ], [ Attribute.GIVEN_NAME, (str) => (0, util_1.toSentenceCase)(str.split(' ')[0]), (str) => (0, util_1.isFullName)(str) ], [ Attribute.FAMILY_NAME, (str) => (0, util_1.toSentenceCase)(str.split(' ').reduce((_, c) => c, '')), (str) => (0, util_1.isFullName)(str), true ], [ Attribute.BIRTHDATE, (str) => (0, util_1.formatDate)(str), (str) => (0, util_1.isDatePattern)(str), true ], [ Attribute.GENDER, (str) => (0, util_1.formatGender)(str), (str) => (0, util_1.isGender)(str) ] ] }, '10': { type: 'Registration sticker', model: [ [ Attribute.REGISTRATION_DISTRICT, (str) => str, (str) => (0, util_1.isGeneralString)(str), true ], [ Attribute.REGISTRATION_DATE, (str) => (0, util_1.formatDate)(str), (str) => (0, util_1.isDatePattern)(str), true ], [ Attribute.REGISTRATION_TA, (str) => str, (str) => (0, util_1.isGeneralString)(str), true ], [ Attribute.REGISTRATION_VILLAGE, (str) => str, (str) => (0, util_1.isGeneralString)(str), true ], [ Attribute.NATIONAL_ID, (str) => str, (str) => (0, util_1.isValidNationalID)(str), true ], [ Attribute.FAMILY_NAME, (str) => (0, util_1.toSentenceCase)(str), (str) => (0, util_1.isFullName)(str), true ], [ Attribute.GIVEN_NAME, (str) => (0, util_1.toSentenceCase)(str), (str) => (0, util_1.isFullName)(str), true ], [ Attribute.BIRTHDATE, (str) => (0, util_1.formatDate)(str), (str) => (0, util_1.isDatePattern)(str), true ] ] } }; function parseNrbQr(code) { // First character in array index indicate type of identifier that was scanned const [docType, ...data] = `${code}`.split('~'); // Supported documents are mapped in SUPPORTED_DOCS. if (!SUPPORTED_DOCS[docType]) return; return data.reduce((dataMap, codeValue) => { // Maintain a list of attributes that haven't been mapped yet const availableAttributes = SUPPORTED_DOCS[docType].model.filter((val) => !Object.keys(dataMap).includes(val[0])); for (const struct of availableAttributes) { const [attribute, formatValue, matchToPattern, breaker] = struct; const value = `${codeValue}`.trim(); if (matchToPattern(value, dataMap)) { dataMap[attribute] = formatValue(value); // Do not proceed evaluating other attributes if certainity is explicitly defined if (breaker) break; } } return dataMap; }, { docType: SUPPORTED_DOCS[docType].type }); } exports.parseNrbQr = parseNrbQr;