react-native-healthkit-bridge
Version:
A comprehensive React Native bridge for Apple HealthKit with TypeScript support, advanced authorization, and flexible data queries
127 lines (126 loc) • 3.75 kB
JavaScript
import { HEALTHKIT_CONFIG } from '../config/healthkit.config';
export class HealthKitValidator {
static validateIdentifier(identifier) {
if (!identifier || typeof identifier !== 'string') {
return false;
}
if (identifier.length > HEALTHKIT_CONFIG.VALIDATION.MAX_IDENTIFIER_LENGTH) {
return false;
}
if (!/^[a-zA-Z0-9_]+$/.test(identifier)) {
return false;
}
return true;
}
static validateDateRange(start, end) {
if (!start || !end || !(start instanceof Date) || !(end instanceof Date)) {
return false;
}
if (start >= end) {
return false;
}
const range = end.getTime() - start.getTime();
if (range < HEALTHKIT_CONFIG.VALIDATION.MIN_DATE_RANGE) {
return false;
}
if (range > HEALTHKIT_CONFIG.VALIDATION.MAX_DATE_RANGE) {
return false;
}
return true;
}
static validateDays(days) {
if (!Number.isInteger(days) || days < HEALTHKIT_CONFIG.VALIDATION.MIN_DAYS || days > HEALTHKIT_CONFIG.VALIDATION.MAX_DAYS) {
return false;
}
return true;
}
static validateUnit(unit) {
if (!unit || typeof unit !== 'string') {
return false;
}
// Unidades válidas do HealthKit
const validUnits = [
'count',
'm',
'km',
'mi',
'yd',
'ft',
'kcal',
'kJ',
'count/min',
'bpm',
'kg',
'lb',
'g',
'oz',
'mmHg',
'mg/dL',
'mmol/L',
'%',
'C',
'F',
'L',
'mL',
'gal',
'qt',
'pt',
'cup',
'tbsp',
'tsp',
'in',
'cm',
'mm',
'min'
];
return validUnits.includes(unit);
}
static validateIdentifiers(identifiers) {
if (!Array.isArray(identifiers) || identifiers.length === 0) {
return false;
}
if (identifiers.length > HEALTHKIT_CONFIG.VALIDATION.MAX_BATCH_SIZE) {
return false;
}
return identifiers.every(identifier => this.validateIdentifier(identifier));
}
static validateQueryOptions(options) {
if (!options || typeof options !== 'object') {
return false;
}
if (options.startDate && !(options.startDate instanceof Date)) {
return false;
}
if (options.endDate && !(options.endDate instanceof Date)) {
return false;
}
if (options.days && !this.validateDays(options.days)) {
return false;
}
if (options.limit && (!Number.isInteger(options.limit) || options.limit <= 0)) {
return false;
}
if (options.ascending !== undefined && typeof options.ascending !== 'boolean') {
return false;
}
return true;
}
static validateAuthorizationRequest(identifiers) {
return this.validateIdentifiers(identifiers);
}
static getValidationErrors(validationResults) {
const errors = [];
Object.entries(validationResults).forEach(([field, isValid]) => {
if (!isValid) {
errors.push(`Campo '${field}' é inválido`);
}
});
return errors;
}
static sanitizeIdentifier(identifier) {
return identifier.trim().replace(/[^a-zA-Z0-9_]/g, '');
}
static sanitizeUnit(unit) {
return unit.trim().toLowerCase();
}
}