UNPKG

natural-time-js

Version:

Natural time is a fresh, elegant, and coherent way of measuring the movements of time here on the Earth. This new time standard is based on common sense and the observation of natural cycles. Learn more: https://naturaltime.app. This JavaScript Class tran

231 lines 7.76 kB
/** * @module natural-time-js/validators * @description Validation utilities for natural time calculations. * This module provides functions to validate inputs for natural time operations, * ensuring that values are within acceptable ranges and of the correct types. */ import { NaturalDate } from '../core/NaturalDate.js'; /** * Valid range for latitude values in degrees */ const LATITUDE_RANGE = { MIN: -90, MAX: 90 }; /** * Valid range for longitude values in degrees */ const LONGITUDE_RANGE = { MIN: -180, MAX: 180 }; /** * Valid range for angle values in degrees */ const ANGLE_RANGE = { MIN: 0, MAX: 360 }; /** * Valid ranges for natural date components */ const NATURAL_DATE_RANGES = { /** Moon (month) number range (1-14) */ MOON: { MIN: 1, MAX: 14 }, /** Week of year range (1-53) */ WEEK: { MIN: 1, MAX: 53 }, /** Week within moon range (1-4) */ WEEK_OF_MOON: { MIN: 1, MAX: 4 }, /** Day of moon range (1-28) */ DAY_OF_MOON: { MIN: 1, MAX: 28 }, /** Day of week range (1-7) */ DAY_OF_WEEK: { MIN: 1, MAX: 7 } }; /** * Validates if a value is a finite number. * * This is a utility function that checks if a value is a valid number * (not NaN, not Infinity, and actually a number type). * * @param value - Value to validate * @returns True if value is a valid number * * @example * isValidNumber(42); // true * isValidNumber('42'); // false (string, not number) * isValidNumber(NaN); // false * isValidNumber(Infinity); // false */ export const isValidNumber = (value) => { return typeof value === 'number' && Number.isFinite(value) && !Number.isNaN(value); }; /** * Validates if a latitude value is within the valid range. * * Latitude must be a number between -90° (South Pole) and 90° (North Pole). * * @param latitude - Latitude in degrees to validate * @returns True if latitude is valid * * @example * isValidLatitude(45.5); // true * isValidLatitude(-90); // true (South Pole) * isValidLatitude(90); // true (North Pole) * isValidLatitude(91); // false (out of range) */ export const isValidLatitude = (latitude) => { return isValidNumber(latitude) && latitude >= LATITUDE_RANGE.MIN && latitude <= LATITUDE_RANGE.MAX; }; /** * Validates if a longitude value is within the valid range. * * Longitude must be a number between -180° and 180°, where: * - 0° is the Prime Meridian (Greenwich) * - Positive values are East longitude * - Negative values are West longitude * * @param longitude - Longitude in degrees to validate * @returns True if longitude is valid * * @example * isValidLongitude(0); // true (Prime Meridian) * isValidLongitude(180); // true (International Date Line) * isValidLongitude(-180); // true (International Date Line) * isValidLongitude(181); // false (out of range) */ export const isValidLongitude = (longitude) => { return isValidNumber(longitude) && longitude >= LONGITUDE_RANGE.MIN && longitude <= LONGITUDE_RANGE.MAX; }; /** * Validates if an angle value is within the valid range. * * Angles in natural time are measured in degrees from 0° to 360°, * representing a full circle. This is used for time of day and * celestial positions. * * @param angle - Angle in degrees to validate * @returns True if angle is valid * * @example * isValidAngle(180); // true (half circle) * isValidAngle(360); // true (full circle) * isValidAngle(0); // true (beginning of circle) * isValidAngle(361); // false (out of range) * isValidAngle(-1); // false (out of range) */ export const isValidAngle = (angle) => { return isValidNumber(angle) && angle >= ANGLE_RANGE.MIN && angle <= ANGLE_RANGE.MAX; }; /** * Validates if a timestamp is a valid Unix time. * * Unix timestamps represent the number of milliseconds since * January 1, 1970, 00:00:00 UTC (the Unix epoch). * Valid timestamps must be positive numbers. * * @param timestamp - Unix timestamp in milliseconds * @returns True if timestamp is valid * * @example * isValidTimestamp(Date.now()); // true * isValidTimestamp(0); // false (Unix epoch exactly) * isValidTimestamp(-1); // false (before Unix epoch) */ export const isValidTimestamp = (timestamp) => { return isValidNumber(timestamp) && timestamp > 0; }; /** * Validates if an object is a properly initialized NaturalDate instance. * * This function performs a comprehensive check of a NaturalDate object, * verifying that all properties are present and within valid ranges. * It's used to ensure that only valid NaturalDate objects are used in calculations. * * @param date - Value to validate * @returns True if value is a valid NaturalDate instance * * @example * const naturalDate = new NaturalDate(new Date(), 0); * isValidNaturalDate(naturalDate); // true * * isValidNaturalDate({}); // false (not a NaturalDate instance) * isValidNaturalDate(null); // false */ export const isValidNaturalDate = (date) => { if (!(date instanceof NaturalDate)) { return false; } // Basic property validations if (!isValidTimestamp(date.unixTime) || !isValidLongitude(date.longitude) || !isValidNumber(date.year)) { return false; } // Natural calendar validations return (isValidNumber(date.moon) && date.moon >= NATURAL_DATE_RANGES.MOON.MIN && date.moon <= NATURAL_DATE_RANGES.MOON.MAX && isValidNumber(date.week) && date.week >= NATURAL_DATE_RANGES.WEEK.MIN && date.week <= NATURAL_DATE_RANGES.WEEK.MAX && isValidNumber(date.weekOfMoon) && date.weekOfMoon >= NATURAL_DATE_RANGES.WEEK_OF_MOON.MIN && date.weekOfMoon <= NATURAL_DATE_RANGES.WEEK_OF_MOON.MAX && isValidNumber(date.dayOfMoon) && date.dayOfMoon >= NATURAL_DATE_RANGES.DAY_OF_MOON.MIN && date.dayOfMoon <= NATURAL_DATE_RANGES.DAY_OF_MOON.MAX && isValidNumber(date.dayOfWeek) && date.dayOfWeek >= NATURAL_DATE_RANGES.DAY_OF_WEEK.MIN && date.dayOfWeek <= NATURAL_DATE_RANGES.DAY_OF_WEEK.MAX && isValidNumber(date.dayOfYear) && date.dayOfYear >= 1 && date.dayOfYear <= date.yearDuration && typeof date.isRainbowDay === 'boolean' && isValidAngle(date.time) && isValidTimestamp(date.yearStart) && isValidNumber(date.yearDuration) && isValidTimestamp(date.nadir)); }; /** * Validates if a string is a valid cache key. * * Cache keys are used for storing and retrieving calculated values * to improve performance. Valid keys must be non-empty strings. * * @param key - Cache key to validate * @returns True if key is valid * * @example * isValidCacheKey('SUN_2023_45.5_0'); // true * isValidCacheKey(''); // false (empty string) * isValidCacheKey(123); // false (not a string) */ export const isValidCacheKey = (key) => { return typeof key === 'string' && key.length > 0; }; /** * Throws a formatted error for invalid parameters. * * This utility function creates consistent error messages for validation failures, * making it easier to identify and fix issues with invalid inputs. * * @param paramName - Name of the invalid parameter * @param value - Invalid value * @param expectedType - Description of expected type/format * @throws {Error} Formatted validation error * * @example * // If latitude is invalid: * throwValidationError('latitude', 95, 'number between -90 and 90'); * // Throws: "Error: Invalid latitude: 95. Expected number between -90 and 90" */ export const throwValidationError = (paramName, value, expectedType) => { throw new Error(`Invalid ${paramName}: ${value}. Expected ${expectedType}`); }; //# sourceMappingURL=validators.js.map