smart-vista-ber-tlv
v1.0.0
Published
TypeScript library for parsing, encoding, and validating Smart Vista BER-TLV data structures.
Readme
Smart Vista BER-TLV Parser & Encoder
An enterprise-grade, high-level TypeScript library powered by Bun for parsing, encoding, and validating Smart Vista BER-TLV data structures.
This library abstracts the highly complex, nested, and low-level hexadecimal Tag-Length-Value (TLV) layouts specified by the Smart Vista Back-Office (SVBO) interface into type-safe, human-readable TypeScript models and enums. It hides complex structural nesting, automatic block sequence identifiers (DF805D), and transaction linkages (e.g. Account-to-Card DF8061 connections).
Current scope: this library supports BTRT01, BTRT02, BTRT05, and BTRT15 application flows plus the file header/trailer records. The Smart Vista spec defines many additional application types, but they are not implemented yet in this package.
✨ Features
- Recursive TLV Core Engine: Low-level parser/encoder supporting multi-byte tags, variable-length fields, and indefinite/long-form length encoding according to standard BER-TLV specs.
- High-Level Abstraction Mapping: Translates raw hexadecimal tags into elegant, readable TS structures (e.g.,
cardholder.person.firstName) instead of cryptic tag IDs likeDF8019. - Multiple Application Types: Supports
BTRT01,BTRT02,BTRT05, andBTRT15in the same interchange file. - Value-Level Decoders: Decodes raw code strings into neat unions (e.g.
Sex: 'MALE' | 'FEMALE'instead of checking forSEXT1vsSEXT2). - Validation Engine: Performs thorough validation of business constraints, date formats (
YYYY-MM-DD), numeric formatting, and mandatory fields before encoding. - Dual-Mode Encoding & Decoding:
- Hex String Mode: For working with standard ASCII-based transaction interchange files (line-separated hex records).
- Binary Stream Mode: For low-level TCP/IP socket data parsing and raw binary files (using
Uint8Arraybounded by0x0Adelimiters).
- Auto-Linking Engine: Automatically handles block numbering (
DF805D) and reference links (FF3C/DF8061), removing manual reference management.
🚀 Quick Start
Installation
Install the package from npm with your preferred package manager:
npm install smart-vista-ber-tlvbun add smart-vista-ber-tlv1. High-Level Encoding (Generating Hex Files)
The encoder now accepts a single object with this exact shape:
{
FileHeader,
CardholderApplication,
FileTrailer
}CardholderApplication is an array of one or more application records. That array can now contain BTRT01, BTRT02, BTRT05, and BTRT15 objects. FileHeader and FileTrailer are single objects.
Example:
import {
SmartVistaEncoder,
CardholderApplication,
FileHeader,
FileTrailer
} from "smart-vista-ber-tlv";
// 1. Define File Header
const header: FileHeader = {
type: "HEADER",
fileType: "BTRT01",
fileDate: "2026-05-23",
institutionNumber: "001",
agentCode: "MAIN_BRANCH"
};
// 2. Define Cardholder Application (BTRT01)
const application: CardholderApplication = {
type: "BTRT01",
applicationId: "APP_999888",
recordNumber: "1",
contractId: "CONTRACT_001",
primaryFlag: true,
applicationSource: "MSRC1",
officerId: "OFFICER01",
customer: {
id: "CUST_777",
processingMode: "CREATE_NEW",
vipCode: "VIP",
description: "Premium VIP Client",
deliveryAgentCode: "AGENT-001"
},
cardholder: {
person: {
firstName: "James",
surname: "Bond",
dateOfBirth: "1968-04-13",
sex: "MALE",
maritalStatus: "UNMARRIED",
employedStatus: "EMPLOYED",
documentType: "PASSPORT",
documentNumber: "GBR007"
},
address: {
addressType: "RESIDENCE",
city: "London",
street: "10 Downing Street",
zipCode: "SW1A2AA",
country: "GBR"
}
},
card: {
cardNumber: "4000123456789010"
},
account: {
accountNumber: "203011223344"
}
};
// 3. Define File Trailer
const trailer: FileTrailer = {
type: "TRAILER",
numberOfRecords: 1
};
// 4. Wrap everything in the SmartVistaFile object
const file = {
FileHeader: header,
CardholderApplication: [application],
FileTrailer: trailer
};
// 5. Encode to line-separated hex strings (standard Smart Vista interchange text)
const filePayload = SmartVistaEncoder.encode(file);
console.log(filePayload);
// Output:
// FF450BFF490... (Hex string for header)
// FFFF01A2FF2... (Hex string for BTRT01 application with nested structures)
// FF4609FF4A0... (Hex string for trailer)2. High-Level Decoding (Parsing Payload)
Convert raw interchange payloads back into one clear, structured object:
import { SmartVistaDecoder } from "smart-vista-ber-tlv";
const rawInterchange = `FF4516FF4912DF807D06425452543031DF807C0A323032362D30352D3233DF807903303031DF807A0B4D41494E5F4252414E4348
FFFF01... (rest of the payload)`;
const file = SmartVistaDecoder.decode(rawInterchange);
console.log(`Parsed Header: Date ${file.FileHeader.fileDate}, Branch ${file.FileHeader.agentCode}`);
for (const app of file.CardholderApplication) {
console.log(`Parsed App: ${app.cardholder.person.firstName} ${app.cardholder.person.surname}`);
console.log(`Card Number: ${app.card.cardNumber}`);
}
console.log(`Declared Record Count: ${file.FileTrailer.numberOfRecords}`);3. Binary Stream Processing
When communicating directly over a network socket or working with raw binary files, use the byte-level binary APIs:
import { SmartVistaEncoder, SmartVistaDecoder } from "smart-vista-ber-tlv";
// Encode directly to Uint8Array (delimited by 0x0A bytes)
const binaryData = SmartVistaEncoder.encodeToBinary({
FileHeader: header,
CardholderApplication: [application],
FileTrailer: trailer
});
// Decode raw bytes back to the same high-level object shape
const parsedFile = SmartVistaDecoder.decodeBinary(binaryData);4. Validation Engine
Enforce constraints on fields, formats, and mandatory blocks before transmission. By default, the Encoder runs the validator automatically, but you can also use it manually to report details back to a front-end:
import { SmartVistaValidator } from "smart-vista-ber-tlv";
const badRecord = {
type: "BTRT01",
cardholder: {
person: {
firstName: "", // Empty: Invalid!
surname: "Doe",
dateOfBirth: "90/05/12" // Wrong format!
}
},
card: { cardNumber: "4000-1234" } // Non-numeric & too short!
};
const validation = SmartVistaValidator.validate(badRecord as any);
if (!validation.isValid) {
console.log("Validation Errors Found:");
validation.errors.forEach(err => {
console.log(`- [${err.field}]: ${err.message}`);
});
}
// Output:
// - [cardholder.person.firstName]: First Name is mandatory
// - [cardholder.person.dateOfBirth]: Date of birth must be in YYYY-MM-DD format
// - [card.cardNumber]: Card Number must contain only digits
// - [card.cardNumber]: Card Number length must be between 12 and 19 digits
// - [account.accountNumber]: Account Number is mandatory📦 Publishing To npm
Use this checklist before publishing smart-vista-ber-tlv:
- Update
package.jsonfields such asversion,description,license,repository, andkeywords. - Build and test the package locally.
- Confirm the package contents are correct with
npm pack --dry-run. - Log in to npm with
npm login. - Publish with
npm publish --access public.
Example release flow:
npm version patch
npm pack --dry-run
npm publish --access publicIf you prefer token-based auth in CI, use an environment variable instead of committing credentials:
export NPM_TOKEN=your_token_here
printf "//registry.npmjs.org/:_authToken=${NPM_TOKEN}\n" > .npmrc
npm publish --access public
rm .npmrc🗺️ Field-to-Tag Mappings
The library automatically manages the translation between the following properties and their respective Smart Vista tag registry entries:
File Header (FF45 -> FF49)
| High-level Property | Smart Vista Tag | Format | Description |
|---|---|---|---|
| fileType | DF807D | ANS | Interchange layout format (e.g. BTRT01) |
| fileDate | DF807C | Date (YYYY-MM-DD) | Processing timestamp date |
| institutionNumber | DF8079 | Numeric | Acquiring/issuing bank institution ID |
| agentCode | DF807A | ANS | Agent, branch, or partner system ID |
File Trailer (FF46 -> FF4A)
| High-level Property | Smart Vista Tag | Format | Description |
|---|---|---|---|
| numberOfRecords | DF807E | Numeric | Count of records in current payload |
| crc | DF8060 | Hex | Payload checksum/hash total |
Cardholder Application (FFFF01)
Main Block (FF2E)
| High-level Property | Smart Vista Tag | Format | Description |
|---|---|---|---|
| applicationId | DF8041 | ANS | Unique ID for the workflow run |
| applicationStatus | DF834B | ANS | Application processing status (e.g. APRS00) |
Customer Block (FF20)
| High-level Property | Smart Vista Tag | Format | Description |
|---|---|---|---|
| customer.id | DF8003 | ANS | Unique client ID |
| customer.processingMode | DF8108 | Enum String | Mapping to 1, 3, 9 (Create, Use, Update) |
| customer.vipCode | DF8006 | Enum String | Mapping to CVIP0 ... CVIP3 |
| customer.description | DF8004 | ANS | Description of customer status |
| customer.inn | DF8418 | Numeric | Taxpayer identification |
Person Block (FF2C -> FF22)
| High-level Property | Smart Vista Tag | Format | Description |
|---|---|---|---|
| cardholder.person.firstName | DF8019 | ANS | Primary given name |
| cardholder.person.surname | DF801B | ANS | Primary family name |
| cardholder.person.sex | DF8008 | Enum String | Maps MALE, FEMALE, TRANSSEXUAL |
| cardholder.person.maritalStatus | DF8009 | Enum String | Maps marital status keys (MRTS1...) |
| cardholder.person.residence | DF800A | Enum String | Maps residential status (RSDN1...) |
| cardholder.person.employedStatus | DF800E | Enum String | Maps employment status (EMPF0...) |
| cardholder.person.documentType | DF803B | Enum String | Maps ID documents (IDTP1...) |
| cardholder.person.documentNumber | DF803C | ANS | Identification serial code |
Address Block (FF2C -> FF2A)
| High-level Property | Smart Vista Tag | Format | Description |
|---|---|---|---|
| cardholder.address.addressType | DF801E | ANS | Address type identifier |
| cardholder.address.city | DF801F | ANS | Municipality location |
| cardholder.address.street | DF8023 | ANS | Street route and house details |
| cardholder.address.zipCode | DF8022 | ANS | Postal code value |
Card & Account Links (FF24 / FF26 / FF3C)
| High-level Property | Smart Vista Tag | Format | Description |
|---|---|---|---|
| card.cardNumber | FF24 -> FF33 -> DF802C | Numeric | PAN string (12-19 digits) |
| account.accountNumber| FF26 -> FF36 -> DF8033 | Numeric | Bank account number string |
| (Auto-Link) | FF3C -> DF8061 | Hex (XXXXYYYY) | Linked account reference to card |
🛠️ Development & Running Tests
This library includes a comprehensive suite of unit and integration tests written using Bun’s native testing framework.
Run all tests:
bun testProject Structure:
src/core/utils.ts: Binary converters (Hex, ASCII, byte manipulation).src/core/tlv.ts: Core BER-TLV parser and serializer engine.src/schema/enums.ts: Bi-directional enums and code maps.src/schema/models.ts: High-level TypeScript interfaces.src/schema/mapping.ts: Tag mapping and sequence link engine.src/validation/rules.ts: Validator logic for Smart Vista rules.tests/: Automated core, mapping, and validation test suites.
