code-craft-studio
Version:
A comprehensive QR code and barcode scanning/generation library for React. Works with or without Capacitor. Supports 22+ QR data types and 14+ barcode formats (EAN, UPC, Code 128, etc.), with customizable designs, analytics, and React components. Provider
229 lines • 7.46 kB
JavaScript
import { QRType } from '../definitions';
export function validateQRCodeData(data) {
const errors = [];
switch (data.type) {
case QRType.WEBSITE:
case QRType.PDF:
case QRType.VIDEO:
case 'audio':
case QRType.MP3:
if (!data.url || !validateURL(data.url)) {
errors.push('Invalid URL');
}
break;
case QRType.MENU:
if (!data.restaurantName) {
errors.push('Restaurant name is required');
}
if (!data.categories || data.categories.length === 0) {
errors.push('At least one category is required');
}
break;
case QRType.EMAIL:
if (!data.to || !validateEmail(data.to)) {
errors.push('Invalid email address');
}
break;
case QRType.SMS:
case QRType.PHONE:
case QRType.WHATSAPP:
if (!data.phoneNumber || !validatePhoneNumber(data.phoneNumber)) {
errors.push('Invalid phone number');
}
break;
case QRType.LOCATION:
if (typeof data.latitude !== 'number' || typeof data.longitude !== 'number') {
errors.push('Invalid coordinates');
}
break;
case QRType.WIFI:
if (!data.ssid)
errors.push('SSID is required');
if (!data.password)
errors.push('Password is required');
break;
case QRType.EVENT:
if (!data.title)
errors.push('Event title is required');
if (!data.startDate)
errors.push('Start date is required');
if (!data.endDate)
errors.push('End date is required');
break;
case QRType.VCARD:
if (!data.firstName && !data.lastName) {
errors.push('Name is required');
}
break;
case QRType.TEXT:
if (!data.text)
errors.push('Text is required');
break;
}
return {
isValid: errors.length === 0,
errors,
warnings: []
};
}
export function validateBarcodeData(data, format) {
const errors = [];
const warnings = [];
if (!data) {
errors.push('Data is required');
return { isValid: false, errors, warnings };
}
switch (format) {
case 'EAN_13':
if (!/^\d{13}$/.test(data)) {
errors.push('EAN-13 must be exactly 13 digits');
}
else if (!verifyEAN13Checksum(data)) {
errors.push('Invalid EAN-13 checksum');
}
break;
case 'EAN_8':
if (!/^\d{8}$/.test(data)) {
errors.push('EAN-8 must be exactly 8 digits');
}
else if (!verifyEAN8Checksum(data)) {
errors.push('Invalid EAN-8 checksum');
}
break;
case 'UPC_A':
if (!/^\d{12}$/.test(data)) {
errors.push('UPC-A must be exactly 12 digits');
}
else if (!verifyUPCAChecksum(data)) {
errors.push('Invalid UPC-A checksum');
}
break;
case 'UPC_E':
if (!/^\d{8}$/.test(data)) {
errors.push('UPC-E must be exactly 8 digits');
}
break;
case 'CODE_128':
if (data.length > 80) {
warnings.push('Code 128 data is very long, may not scan well');
}
break;
case 'CODE_39':
if (!/^[A-Z0-9\-\.\$\/\+\%\s]+$/.test(data)) {
errors.push('Code 39 can only contain uppercase letters, numbers, and - . $ / + % space');
}
break;
case 'ITF':
if (!/^\d+$/.test(data) || data.length % 2 !== 0) {
errors.push('ITF must contain an even number of digits');
}
break;
case 'CODABAR':
if (!/^[0-9\-\$\:\/\.\+]+$/.test(data)) {
errors.push('Codabar can only contain digits and - $ : / . +');
}
break;
}
return { isValid: errors.length === 0, errors, warnings };
}
// Validation helper functions
export function validateEmail(email) {
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return re.test(email);
}
export function validatePhoneNumber(phone) {
const cleaned = phone.replace(/\D/g, '');
return cleaned.length >= 10 && cleaned.length <= 15;
}
export function validateURL(url) {
try {
new URL(url);
return true;
}
catch (_a) {
return false;
}
}
// Checksum calculation functions
export function calculateEAN13Checksum(data) {
const digits = data.slice(0, 12).split('').map(Number);
let sum = 0;
for (let i = 0; i < 12; i++) {
sum += digits[i] * (i % 2 === 0 ? 1 : 3);
}
return String((10 - (sum % 10)) % 10);
}
export function calculateEAN8Checksum(data) {
const digits = data.slice(0, 7).split('').map(Number);
let sum = 0;
for (let i = 0; i < 7; i++) {
sum += digits[i] * (i % 2 === 0 ? 3 : 1);
}
return String((10 - (sum % 10)) % 10);
}
export function calculateUPCAChecksum(data) {
const digits = data.slice(0, 11).split('').map(Number);
let sum = 0;
for (let i = 0; i < 11; i++) {
sum += digits[i] * (i % 2 === 0 ? 3 : 1);
}
return String((10 - (sum % 10)) % 10);
}
export function calculateUPCEChecksum(data) {
// UPC-E checksum is calculated from the expanded UPC-A
return calculateUPCAChecksum(expandUPCE(data));
}
export function calculateCode128Checksum(data) {
// Simplified Code 128 checksum
let sum = 104; // Start code B
for (let i = 0; i < data.length; i++) {
sum += (data.charCodeAt(i) - 32) * (i + 1);
}
return sum % 103;
}
export function calculateCode39Checksum(data) {
const code39Chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%';
let sum = 0;
for (const char of data) {
sum += code39Chars.indexOf(char);
}
return code39Chars[sum % 43];
}
export function calculateCode93Checksum(_data) {
// Simplified Code 93 checksum
return 'XX'; // Placeholder for two check characters
}
export function calculateITFChecksum(_data) {
// ITF doesn't typically use checksums, but some variants do
return '';
}
export function calculateCodabarChecksum(_data) {
// Codabar doesn't use checksums
return '';
}
// Verification functions
function verifyEAN13Checksum(data) {
const checkDigit = data.slice(-1);
const calculated = calculateEAN13Checksum(data);
return checkDigit === calculated;
}
function verifyEAN8Checksum(data) {
const checkDigit = data.slice(-1);
const calculated = calculateEAN8Checksum(data);
return checkDigit === calculated;
}
function verifyUPCAChecksum(data) {
const checkDigit = data.slice(-1);
const calculated = calculateUPCAChecksum(data);
return checkDigit === calculated;
}
function expandUPCE(upce) {
// Simplified UPC-E to UPC-A expansion
if (upce.length !== 8)
return '000000000000';
const manufacturer = upce.slice(1, 4);
const product = upce.slice(4, 6);
const check = upce.slice(-1);
return '0' + manufacturer + '00000' + product + check;
}
//# sourceMappingURL=validation.js.map