@criapix/saas-assinaturas-client
Version:
SDK JavaScript/TypeScript para o AssinaturasService - Sistema de gestão de assinaturas SaaS com processamento de pagamentos de faturas (cartão, PIX, débito), gerenciamento de métodos de pagamento, pagamentos recorrentes e análise de falhas de pagamento
135 lines (119 loc) • 4.22 kB
text/typescript
/**
* Validates and parses card expiry date from various formats (MM/YY, MM/YYYY, ISO 8601)
*/
export class CardExpiryDateValidator {
/**
* Validates card expiry date format and returns validation result
* @param dateString - Date string in MM/YY, MM/YYYY, or ISO 8601 format
* @returns Validation result with success flag and error message if invalid
*/
static validate(dateString: string): { valid: boolean; error?: string; parsedDate?: Date } {
if (!dateString || typeof dateString !== 'string') {
return { valid: false, error: 'Card expiry date is required' };
}
const trimmed = dateString.trim();
if (trimmed.length === 0) {
return { valid: false, error: 'Card expiry date cannot be empty' };
}
// Try to parse MM/YY or MM/YYYY format
const cardFormatResult = this.tryParseCardFormat(trimmed);
if (cardFormatResult.success) {
if (cardFormatResult.date! < new Date()) {
return { valid: false, error: 'Card expiry date must be in the future' };
}
return { valid: true, parsedDate: cardFormatResult.date };
}
// Try to parse ISO 8601 format
const isoDate = new Date(trimmed);
if (!isNaN(isoDate.getTime())) {
if (isoDate < new Date()) {
return { valid: false, error: 'Card expiry date must be in the future' };
}
return { valid: true, parsedDate: isoDate };
}
return {
valid: false,
error: `Invalid card expiry date format: '${dateString}'. Supported formats: 'MM/YY', 'MM/YYYY', or ISO 8601 (e.g., '2030-11-30T00:00:00Z')`,
};
}
/**
* Parses card expiry date from string to Date object
* @param dateString - Date string in MM/YY, MM/YYYY, or ISO 8601 format
* @returns Parsed Date object
* @throws Error if format is invalid
*/
static parse(dateString: string): Date {
const result = this.validate(dateString);
if (!result.valid) {
throw new Error(result.error);
}
return result.parsedDate!;
}
/**
* Normalizes card expiry date to ISO 8601 format for API calls
* @param dateString - Date string in any supported format
* @returns ISO 8601 formatted date string
*/
static normalize(dateString: string): string {
const parsedDate = this.parse(dateString);
return parsedDate.toISOString();
}
/**
* Tries to parse MM/YY or MM/YYYY format
* @param input - Input date string
* @returns Parse result with success flag and date if successful
*/
private static tryParseCardFormat(input: string): { success: boolean; date?: Date } {
const parts = input.split('/');
if (parts.length !== 2) {
return { success: false };
}
const month = parseInt(parts[0], 10);
let year = parseInt(parts[1], 10);
// Validate month
if (isNaN(month) || month < 1 || month > 12) {
return { success: false };
}
// Validate year
if (isNaN(year)) {
return { success: false };
}
// Convert YY to YYYY (assume 20xx century)
if (year < 100) {
year += 2000;
}
// Card expires at the end of the month
try {
const daysInMonth = new Date(year, month, 0).getDate();
const date = new Date(Date.UTC(year, month - 1, daysInMonth, 23, 59, 59));
return { success: true, date };
} catch {
return { success: false };
}
}
}
/**
* Convenience function to validate card expiry date
* @param dateString - Date string to validate
* @returns true if valid, false otherwise
*/
export function isValidCardExpiryDate(dateString: string): boolean {
return CardExpiryDateValidator.validate(dateString).valid;
}
/**
* Convenience function to parse card expiry date
* @param dateString - Date string to parse
* @returns Parsed Date object
* @throws Error if format is invalid
*/
export function parseCardExpiryDate(dateString: string): Date {
return CardExpiryDateValidator.parse(dateString);
}
/**
* Convenience function to normalize card expiry date to ISO 8601
* @param dateString - Date string to normalize
* @returns ISO 8601 formatted date string
*/
export function normalizeCardExpiryDate(dateString: string): string {
return CardExpiryDateValidator.normalize(dateString);
}