UNPKG

promptparse

Version:

All-in-one JS library for PromptPay & EMVCo QR Codes

1 lines 19.3 kB
{"version":3,"sources":["/home/runner/work/promptparse/promptparse/dist/chunk-MWOLRUVR.mjs","../src/validate/index.ts","../src/lib/EMVCoQR.ts","../src/lib/parser.ts","../src/validate/bcel/BCELOneProof.ts","../src/validate/promptpay/AnyID.ts","../src/validate/promptpay/BillPayment.ts","../src/validate/promptpay/SlipVerify.ts","../src/validate/truemoney/TrueMoneySlipVerify.ts"],"names":["BOTBarcode","ProxyType","__export","__publicField","checksum","decode","encode","get","withCrcTag","validate_exports","anyId","bcelOneProof","billPayment","slipVerify","trueMoneySlipVerify","EMVCoQR","payload","tags","getTag","tagId","subTagId","getTagValue","value","getTags","getPayload","validate","crcTagId","filter","f","id","expected","parse","strict","subTags","match","slice","toUpperCase","calculated","length","tag","sub","every","val","parseBarcode","fromString","ppqr","type","ticket","fccref","aidType","tag29Aid","proxyTypeEntry","Object","entries","find","target","startsWith","amountStr","amount","parseFloat","tag30Aid","billerId","ref1","ref2","ref3","crcAutoFix","idx","lastIndexOf","crc","substring","padStart","apiType","sendingBank","transRef","eventType","transactionId","date"],"mappings":"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","sourcesContent":["import {\n BOTBarcode,\n ProxyType,\n __export,\n __publicField,\n checksum,\n decode,\n encode,\n get,\n withCrcTag\n} from \"./chunk-5EIJJBFC.mjs\";\n\n// src/validate/index.ts\nvar validate_exports = {};\n__export(validate_exports, {\n anyId: () => anyId,\n bcelOneProof: () => bcelOneProof,\n billPayment: () => billPayment,\n slipVerify: () => slipVerify,\n trueMoneySlipVerify: () => trueMoneySlipVerify\n});\n\n// src/lib/EMVCoQR.ts\nvar EMVCoQR = class {\n constructor(payload, tags) {\n __publicField(this, \"payload\");\n __publicField(this, \"tags\");\n this.payload = payload;\n this.tags = tags;\n }\n getTag(tagId, subTagId) {\n return get(this.tags, tagId, subTagId);\n }\n getTagValue(tagId, subTagId) {\n return this.getTag(tagId, subTagId)?.value;\n }\n getTags() {\n return this.tags;\n }\n /* c8 ignore next 3 */\n getPayload() {\n return this.payload;\n }\n validate(crcTagId) {\n const tags = [...this.tags].filter((f) => f.id != crcTagId);\n const expected = withCrcTag(encode(tags), crcTagId);\n return this.payload === expected;\n }\n};\n\n// src/lib/parser.ts\nfunction parse(payload, strict = false, subTags = true) {\n if (!payload.match(/^\\d{4}.+/)) {\n return null;\n }\n if (strict) {\n const expected = payload.slice(-4).toUpperCase();\n const calculated = checksum(payload.slice(0, -4));\n if (expected != calculated) return null;\n }\n const tags = decode(payload);\n if (tags.length == 0) {\n return null;\n }\n if (subTags) {\n for (const tag of tags) {\n if (typeof tag.value !== \"string\" || !tag.value.match(/^\\d{4}.+/)) {\n continue;\n }\n const sub = decode(tag.value);\n if (sub.every((val) => val.length > 0 && val.length === val.value.length)) {\n tag.subTags = sub;\n }\n }\n }\n return new EMVCoQR(payload, tags);\n}\nfunction parseBarcode(payload) {\n return BOTBarcode.fromString(payload);\n}\n\n// src/validate/bcel/BCELOneProof.ts\nfunction bcelOneProof(payload) {\n const ppqr = parse(payload, true);\n const type = ppqr?.getTagValue(\"33\", \"02\");\n const ticket = ppqr?.getTagValue(\"33\", \"03\");\n const fccref = ppqr?.getTagValue(\"33\", \"04\");\n if (ppqr?.getTagValue(\"00\") !== \"01\" && ppqr?.getTagValue(\"01\") !== \"11\" && ppqr?.getTagValue(\"33\", \"00\") !== \"BCEL\" && ppqr?.getTagValue(\"33\", \"00\") !== \"ONEPROOF\") {\n return null;\n }\n return {\n type,\n ticket,\n fccref\n };\n}\n\n// src/validate/promptpay/AnyID.ts\nfunction anyId(payload) {\n const ppqr = parse(payload, true);\n const aidType = ppqr?.getTagValue(\"00\");\n const tag29Aid = ppqr?.getTagValue(\"29\", \"00\");\n if (aidType !== \"01\" || tag29Aid !== \"A000000677010111\") {\n return null;\n }\n const proxyTypeEntry = Object.entries(ProxyType).find(([, id]) => ppqr?.getTagValue(\"29\", id) !== void 0);\n if (!proxyTypeEntry) {\n return null;\n }\n const [type, subTagId] = proxyTypeEntry;\n let target = ppqr.getTagValue(\"29\", subTagId);\n if (type === \"MSISDN\" && target.length == 13 && target.startsWith(\"0066\")) {\n target = \"0\" + target.slice(-9);\n }\n const amountStr = ppqr?.getTagValue(\"54\");\n const amount = amountStr !== void 0 ? parseFloat(amountStr) : void 0;\n return {\n type,\n target,\n ...amount !== void 0 && { amount }\n };\n}\n\n// src/validate/promptpay/BillPayment.ts\nfunction billPayment(payload) {\n const ppqr = parse(payload, true);\n const aidType = ppqr?.getTagValue(\"00\");\n const tag30Aid = ppqr?.getTagValue(\"30\", \"00\");\n const billerId = ppqr?.getTagValue(\"30\", \"01\");\n const ref1 = ppqr?.getTagValue(\"30\", \"02\");\n if (aidType !== \"01\" || tag30Aid !== \"A000000677010112\" || !billerId || !ref1) {\n return null;\n }\n const ref2 = ppqr?.getTagValue(\"30\", \"03\");\n const ref3 = ppqr?.getTagValue(\"62\", \"07\");\n const amountStr = ppqr?.getTagValue(\"54\");\n const amount = amountStr !== void 0 ? parseFloat(amountStr) : void 0;\n return {\n billerId,\n ref1,\n ...ref2 !== void 0 && { ref2 },\n ...ref3 !== void 0 && { ref3 },\n ...amount !== void 0 && { amount }\n };\n}\n\n// src/validate/promptpay/SlipVerify.ts\nfunction slipVerify(payload, crcAutoFix = true) {\n if (crcAutoFix) {\n const idx = payload.lastIndexOf(\"9104\");\n if (idx != -1) {\n const crc = payload.substring(idx + 4);\n if (crc.length > 0 && crc.length < 4) {\n payload = payload.substring(0, idx + 4) + crc.padStart(4, \"0\");\n }\n }\n }\n const ppqr = parse(payload, true);\n const apiType = ppqr?.getTagValue(\"00\", \"00\");\n const sendingBank = ppqr?.getTagValue(\"00\", \"01\");\n const transRef = ppqr?.getTagValue(\"00\", \"02\");\n if (apiType !== \"000001\" || !sendingBank || !transRef) {\n return null;\n }\n return {\n sendingBank,\n transRef\n };\n}\n\n// src/validate/truemoney/TrueMoneySlipVerify.ts\nfunction trueMoneySlipVerify(payload) {\n const ppqr = parse(payload, true);\n const eventType = ppqr?.getTagValue(\"00\", \"02\");\n const transactionId = ppqr?.getTagValue(\"00\", \"03\");\n const date = ppqr?.getTagValue(\"00\", \"04\");\n if (ppqr?.getTagValue(\"00\", \"00\") !== \"01\" && ppqr?.getTagValue(\"00\", \"01\") !== \"01\") {\n return null;\n }\n return {\n eventType,\n transactionId,\n date\n };\n}\n\nexport {\n EMVCoQR,\n parse,\n parseBarcode,\n bcelOneProof,\n anyId,\n billPayment,\n slipVerify,\n trueMoneySlipVerify,\n validate_exports\n};\n","export * from './bcel/BCELOneProof'\nexport * from './promptpay/AnyID'\nexport * from './promptpay/BillPayment'\nexport * from './promptpay/SlipVerify'\nexport * from './truemoney/TrueMoneySlipVerify'\n","import { type TLVTag, encode, get, withCrcTag } from '@/lib/tlv'\n\nexport class EMVCoQR {\n private payload: string\n private tags: TLVTag[]\n\n constructor(payload: string, tags: TLVTag[]) {\n this.payload = payload\n this.tags = tags\n }\n\n public getTag(tagId: string, subTagId?: string) {\n return get(this.tags, tagId, subTagId)\n }\n\n public getTagValue(tagId: string, subTagId?: string) {\n return this.getTag(tagId, subTagId)?.value\n }\n\n public getTags() {\n return this.tags\n }\n\n /* c8 ignore next 3 */\n public getPayload() {\n return this.payload\n }\n\n public validate(crcTagId: string) {\n const tags = [...this.tags].filter((f) => f.id != crcTagId)\n const expected = withCrcTag(encode(tags), crcTagId)\n return this.payload === expected\n }\n}\n","import { BOTBarcode } from '@/lib/BOTBarcode'\nimport { EMVCoQR } from '@/lib/EMVCoQR'\nimport { checksum, decode } from '@/lib/tlv'\n\n/**\n * Parse any EMVCo-compatible QR Code data string\n *\n * @param payload - QR Code data string from the scanner\n * @param strict - Validate CRC checksum before parsing the entire string\n * @param subTags - Parse TLV Sub-tags (If exists)\n * @returns QR Instance with TLV Tags\n */\nexport function parse(payload: string, strict = false, subTags = true) {\n if (!payload.match(/^\\d{4}.+/)) {\n return null\n }\n\n if (strict) {\n const expected = payload.slice(-4).toUpperCase()\n const calculated = checksum(payload.slice(0, -4))\n if (expected != calculated) return null\n }\n\n const tags = decode(payload)\n /* c8 ignore next 3 */\n if (tags.length == 0) {\n return null\n }\n\n if (subTags) {\n for (const tag of tags) {\n if (typeof tag.value !== 'string' || !tag.value.match(/^\\d{4}.+/)) {\n continue\n }\n\n const sub = decode(tag.value)\n if (\n sub.every((val) => val.length > 0 && val.length === val.value.length)\n ) {\n tag.subTags = sub\n }\n }\n }\n\n return new EMVCoQR(payload, tags)\n}\n\n/**\n * Parse barcode data string (BOT Barcode Standard)\n *\n * @param payload - Barcode data string from the scanner\n * @returns BOT Barcode Instance\n */\nexport function parseBarcode(payload: string) {\n return BOTBarcode.fromString(payload)\n}\n","import { parse } from '@/lib/parser'\n\n/**\n * Validate & extract data from BCEL OneProof QR\n *\n * @param payload - QR Code Payload\n * @returns Type, Ticket No. and Reference No. or null if payload invalid\n */\nexport function bcelOneProof(payload: string) {\n const ppqr = parse(payload, true)\n\n const type = ppqr?.getTagValue('33', '02')\n const ticket = ppqr?.getTagValue('33', '03')\n const fccref = ppqr?.getTagValue('33', '04')\n\n if (\n ppqr?.getTagValue('00') !== '01' &&\n ppqr?.getTagValue('01') !== '11' &&\n ppqr?.getTagValue('33', '00') !== 'BCEL' &&\n ppqr?.getTagValue('33', '00') !== 'ONEPROOF'\n ) {\n return null\n }\n\n return {\n type,\n ticket,\n fccref,\n }\n}\n","import { ProxyType } from '@/generate/promptpay/AnyID'\nimport { parse } from '@/lib/parser'\n\n/**\n * Validate & extract data from PromptPay AnyID (Tag 29) QR Code\n *\n * @param payload - QR Code Payload\n * @returns Proxy type, target identifier and optional amount or null if payload invalid\n */\nexport function anyId(payload: string) {\n const ppqr = parse(payload, true)\n\n const aidType = ppqr?.getTagValue('00')\n const tag29Aid = ppqr?.getTagValue('29', '00')\n\n if (aidType !== '01' || tag29Aid !== 'A000000677010111') {\n return null\n }\n\n // Resolve proxy type from sub-tag ID\n const proxyTypeEntry = (\n Object.entries(ProxyType) as [keyof typeof ProxyType, string][]\n ).find(([, id]) => ppqr?.getTagValue('29', id) !== undefined)\n\n if (!proxyTypeEntry) {\n return null\n }\n\n const [type, subTagId] = proxyTypeEntry\n let target = ppqr!.getTagValue('29', subTagId)!\n\n // Normalise MSISDN back to local format (0XXXXXXXXX)\n if (type === 'MSISDN' && target.length == 13 && target.startsWith('0066')) {\n target = '0' + target.slice(-9)\n }\n\n const amountStr = ppqr?.getTagValue('54')\n const amount = amountStr !== undefined ? parseFloat(amountStr) : undefined\n\n return {\n type,\n target,\n ...(amount !== undefined && { amount }),\n }\n}\n","import { parse } from '@/lib/parser'\n\n/**\n * Validate & extract data from PromptPay Bill Payment (Tag 30) QR Code\n *\n * @param payload - QR Code Payload\n * @returns Biller ID, references and optional amount or null if payload invalid\n */\nexport function billPayment(payload: string) {\n const ppqr = parse(payload, true)\n\n const aidType = ppqr?.getTagValue('00')\n const tag30Aid = ppqr?.getTagValue('30', '00')\n const billerId = ppqr?.getTagValue('30', '01')\n const ref1 = ppqr?.getTagValue('30', '02')\n\n if (aidType !== '01' || tag30Aid !== 'A000000677010112' || !billerId || !ref1) {\n return null\n }\n\n const ref2 = ppqr?.getTagValue('30', '03')\n const ref3 = ppqr?.getTagValue('62', '07')\n\n const amountStr = ppqr?.getTagValue('54')\n const amount = amountStr !== undefined ? parseFloat(amountStr) : undefined\n\n return {\n billerId,\n ref1,\n ...(ref2 !== undefined && { ref2 }),\n ...(ref3 !== undefined && { ref3 }),\n ...(amount !== undefined && { amount }),\n }\n}\n","import { parse } from '@/lib/parser'\n\n/**\n * Validate & extract data from Slip Verify QR (for use with Bank Open API)\n *\n * @param payload - QR Code Payload\n * @param crcAutoFix - Attempt to fix bad checksum from bank app\n * @returns Bank code and Transaction reference or null if payload invalid\n */\nexport function slipVerify(payload: string, crcAutoFix = true) {\n if (crcAutoFix) {\n const idx = payload.lastIndexOf('9104')\n if (idx != -1) {\n const crc = payload.substring(idx + 4)\n if (crc.length > 0 && crc.length < 4) {\n payload = payload.substring(0, idx + 4) + crc.padStart(4, '0')\n }\n }\n }\n\n const ppqr = parse(payload, true)\n\n const apiType = ppqr?.getTagValue('00', '00')\n const sendingBank = ppqr?.getTagValue('00', '01')\n const transRef = ppqr?.getTagValue('00', '02')\n\n if (apiType !== '000001' || !sendingBank || !transRef) {\n return null\n }\n\n return {\n sendingBank,\n transRef,\n }\n}\n","import { parse } from '@/lib/parser'\n\n/**\n * Validate & extract data from TrueMoney Slip Verify QR\n *\n * @param payload - QR Code Payload\n * @returns Type, Transaction ID and Date (DDMMYYYY) or null if payload invalid\n */\nexport function trueMoneySlipVerify(payload: string) {\n const ppqr = parse(payload, true)\n\n const eventType = ppqr?.getTagValue('00', '02')\n const transactionId = ppqr?.getTagValue('00', '03')\n const date = ppqr?.getTagValue('00', '04')\n\n if (\n ppqr?.getTagValue('00', '00') !== '01' &&\n ppqr?.getTagValue('00', '01') !== '01'\n ) {\n return null\n }\n\n return {\n eventType,\n transactionId,\n date,\n }\n}\n"]}