{"version":3,"file":"date.mjs","names":[],"sources":["../../../../../../../../@warlock.js/seal/src/rules/date/date.ts"],"sourcesContent":["import { get } from \"@mongez/reinforcements\";\r\nimport { invalidRule, VALID_RULE } from \"../../helpers\";\r\nimport { isDateValue } from \"../../helpers/date-helpers\";\r\nimport type { SchemaRule } from \"../../types\";\r\nimport type { WeekDay } from \"../../types/date-types\";\r\nimport { WEEK_DAYS } from \"../../types/date-types\";\r\n\r\n/**\r\n * Date rule - validates date format\r\n */\r\nexport const dateRule: SchemaRule = {\r\n  name: \"date\",\r\n  defaultErrorMessage: \"The :input must be a valid date\",\r\n  async validate(value: any, context) {\r\n    if (value instanceof Date && !isNaN(value.getTime())) {\r\n      return VALID_RULE;\r\n    }\r\n\r\n    return invalidRule(this, context);\r\n  },\r\n};\r\n\r\n/**\r\n * Min date rule - date must be >= given date or field\r\n * Smart detection: date value or field name\r\n */\r\nexport const minDateRule: SchemaRule<{\r\n  dateOrField: Date | string | number;\r\n  scope?: \"global\" | \"sibling\";\r\n}> = {\r\n  name: \"minDate\",\r\n  description: \"The field must be at least the given date or field\",\r\n  defaultErrorMessage: \"The :input must be at least :dateOrField\",\r\n  async validate(value: Date, context) {\r\n    const { dateOrField, scope = \"global\" } = this.context.options;\r\n    let compareDate: Date;\r\n\r\n    if (isDateValue(dateOrField)) {\r\n      // Value comparison\r\n      compareDate = new Date(dateOrField);\r\n    } else {\r\n      // Field comparison\r\n      const source = scope === \"sibling\" ? context.parent : context.allValues;\r\n      const fieldValue = get(source, dateOrField as string);\r\n\r\n      if (fieldValue === undefined) {\r\n        return VALID_RULE;\r\n      }\r\n\r\n      compareDate = new Date(fieldValue);\r\n    }\r\n\r\n    const inputDate = new Date(value);\r\n\r\n    if (inputDate >= compareDate) {\r\n      return VALID_RULE;\r\n    }\r\n    return invalidRule(this, context);\r\n  },\r\n};\r\n\r\n/**\r\n * Max date rule - date must be <= given date or field\r\n * Smart detection: date value or field name\r\n */\r\nexport const maxDateRule: SchemaRule<{\r\n  dateOrField: Date | string | number;\r\n  scope?: \"global\" | \"sibling\";\r\n}> = {\r\n  name: \"maxDate\",\r\n  defaultErrorMessage: \"The :input must be at most :dateOrField\",\r\n  async validate(value: Date, context) {\r\n    const { dateOrField, scope = \"global\" } = this.context.options;\r\n    let compareDate: Date;\r\n\r\n    if (isDateValue(dateOrField)) {\r\n      // Value comparison\r\n      compareDate = new Date(dateOrField);\r\n    } else {\r\n      // Field comparison\r\n      const source = scope === \"sibling\" ? context.parent : context.allValues;\r\n      const fieldValue = get(source, dateOrField as string);\r\n\r\n      if (fieldValue === undefined) {\r\n        return VALID_RULE;\r\n      }\r\n\r\n      compareDate = new Date(fieldValue);\r\n    }\r\n\r\n    const inputDate = new Date(value);\r\n\r\n    if (inputDate <= compareDate) {\r\n      return VALID_RULE;\r\n    }\r\n    return invalidRule(this, context);\r\n  },\r\n};\r\n\r\n/**\r\n * From today rule - date must be today or in the future\r\n */\r\nexport const fromTodayRule: SchemaRule = {\r\n  name: \"fromToday\",\r\n  defaultErrorMessage: \"The :input must be today or in the future\",\r\n  async validate(value: Date, context) {\r\n    const today = new Date();\r\n    today.setHours(0, 0, 0, 0);\r\n    const inputDate = new Date(value);\r\n    inputDate.setHours(0, 0, 0, 0);\r\n\r\n    if (inputDate >= today) {\r\n      return VALID_RULE;\r\n    }\r\n    return invalidRule(this, context);\r\n  },\r\n};\r\n\r\n/**\r\n * Before today rule - date must be before today\r\n */\r\nexport const beforeTodayRule: SchemaRule = {\r\n  name: \"beforeToday\",\r\n  defaultErrorMessage: \"The :input must be before today\",\r\n  async validate(value: Date, context) {\r\n    const today = new Date();\r\n    today.setHours(0, 0, 0, 0);\r\n    const inputDate = new Date(value);\r\n    inputDate.setHours(0, 0, 0, 0);\r\n\r\n    if (inputDate < today) {\r\n      return VALID_RULE;\r\n    }\r\n    return invalidRule(this, context);\r\n  },\r\n};\r\n\r\n/**\r\n * From hour rule - time must be from specific hour onwards\r\n */\r\nexport const fromHourRule: SchemaRule<{ hour: number }> = {\r\n  name: \"fromHour\",\r\n  defaultErrorMessage: \"The :input must be from :hour:00 onwards\",\r\n  async validate(value: Date, context) {\r\n    const inputDate = new Date(value);\r\n    const hour = inputDate.getHours();\r\n\r\n    if (hour >= this.context.options.hour) {\r\n      return VALID_RULE;\r\n    }\r\n\r\n    this.context.translationParams.hour = this.context.options.hour;\r\n    return invalidRule(this, context);\r\n  },\r\n};\r\n\r\n/**\r\n * Before hour rule - time must be before specific hour\r\n */\r\nexport const beforeHourRule: SchemaRule<{ hour: number }> = {\r\n  name: \"beforeHour\",\r\n  defaultErrorMessage: \"The :input must be before :hour:00\",\r\n  async validate(value: Date, context) {\r\n    const inputDate = new Date(value);\r\n    const hour = inputDate.getHours();\r\n\r\n    if (hour < this.context.options.hour) {\r\n      return VALID_RULE;\r\n    }\r\n\r\n    this.context.translationParams.hour = this.context.options.hour;\r\n    return invalidRule(this, context);\r\n  },\r\n};\r\n\r\n/**\r\n * Between hours rule - time must be between start and end hours\r\n */\r\nexport const betweenHoursRule: SchemaRule<{\r\n  startHour: number;\r\n  endHour: number;\r\n}> = {\r\n  name: \"betweenHours\",\r\n  defaultErrorMessage: \"The :input must be between :startHour:00 and :endHour:00\",\r\n  async validate(value: Date, context) {\r\n    const inputDate = new Date(value);\r\n    const hour = inputDate.getHours();\r\n    const { startHour, endHour } = this.context.options;\r\n\r\n    if (hour >= startHour && hour <= endHour) {\r\n      return VALID_RULE;\r\n    }\r\n\r\n    this.context.translationParams.startHour = startHour;\r\n    this.context.translationParams.endHour = endHour;\r\n    return invalidRule(this, context);\r\n  },\r\n};\r\n\r\n/**\r\n * From minute rule - time must be from specific minute onwards\r\n */\r\nexport const fromMinuteRule: SchemaRule<{ minute: number }> = {\r\n  name: \"fromMinute\",\r\n  defaultErrorMessage: \"The :input must be from minute :minute onwards\",\r\n  async validate(value: Date, context) {\r\n    const inputDate = new Date(value);\r\n    const minute = inputDate.getMinutes();\r\n\r\n    if (minute >= this.context.options.minute) {\r\n      return VALID_RULE;\r\n    }\r\n\r\n    this.context.translationParams.minute = this.context.options.minute;\r\n\r\n    return invalidRule(this, context);\r\n  },\r\n};\r\n\r\n/**\r\n * Before minute rule - time must be before specific minute\r\n */\r\nexport const beforeMinuteRule: SchemaRule<{ minute: number }> = {\r\n  name: \"beforeMinute\",\r\n  defaultErrorMessage: \"The :input must be before minute :minute\",\r\n  async validate(value: Date, context) {\r\n    const inputDate = new Date(value);\r\n    const minute = inputDate.getMinutes();\r\n\r\n    if (minute < this.context.options.minute) {\r\n      return VALID_RULE;\r\n    }\r\n\r\n    this.context.translationParams.minute = this.context.options.minute;\r\n\r\n    return invalidRule(this, context);\r\n  },\r\n};\r\n\r\n/**\r\n * Between minutes rule - time must be between start and end minutes\r\n */\r\nexport const betweenMinutesRule: SchemaRule<{\r\n  startMinute: number;\r\n  endMinute: number;\r\n}> = {\r\n  name: \"betweenMinutes\",\r\n  defaultErrorMessage: \"The :input must be between minute :startMinute and :endMinute\",\r\n  async validate(value: Date, context) {\r\n    const inputDate = new Date(value);\r\n    const minute = inputDate.getMinutes();\r\n    const { startMinute, endMinute } = this.context.options;\r\n\r\n    if (minute >= startMinute && minute <= endMinute) {\r\n      return VALID_RULE;\r\n    }\r\n\r\n    this.context.translationParams.startMinute = startMinute;\r\n    this.context.translationParams.endMinute = endMinute;\r\n\r\n    return invalidRule(this, context);\r\n  },\r\n};\r\n\r\n/**\r\n * Age rule - calculate age from date\r\n */\r\nexport const ageRule: SchemaRule<{ years: number }> = {\r\n  name: \"age\",\r\n  defaultErrorMessage: \"The :input must be exactly :years years old\",\r\n  async validate(value: Date, context) {\r\n    const birthDate = new Date(value);\r\n    const today = new Date();\r\n    let age = today.getFullYear() - birthDate.getFullYear();\r\n    const monthDiff = today.getMonth() - birthDate.getMonth();\r\n\r\n    if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {\r\n      age--;\r\n    }\r\n\r\n    if (age === this.context.options.years) {\r\n      return VALID_RULE;\r\n    }\r\n\r\n    this.context.translationParams.years = this.context.options.years;\r\n\r\n    return invalidRule(this, context);\r\n  },\r\n};\r\n\r\n/**\r\n * Min age rule - minimum age requirement\r\n */\r\nexport const minAgeRule: SchemaRule<{ years: number }> = {\r\n  name: \"minAge\",\r\n  defaultErrorMessage: \"The :input must be at least :years years old\",\r\n  async validate(value: Date, context) {\r\n    const birthDate = new Date(value);\r\n    const today = new Date();\r\n    let age = today.getFullYear() - birthDate.getFullYear();\r\n    const monthDiff = today.getMonth() - birthDate.getMonth();\r\n\r\n    if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {\r\n      age--;\r\n    }\r\n\r\n    if (age >= this.context.options.years) {\r\n      return VALID_RULE;\r\n    }\r\n\r\n    this.context.translationParams.years = this.context.options.years;\r\n\r\n    return invalidRule(this, context);\r\n  },\r\n};\r\n\r\n/**\r\n * Max age rule - maximum age requirement\r\n */\r\nexport const maxAgeRule: SchemaRule<{ years: number }> = {\r\n  name: \"maxAge\",\r\n  defaultErrorMessage: \"The :input must be at most :years years old\",\r\n  async validate(value: Date, context) {\r\n    const birthDate = new Date(value);\r\n    const today = new Date();\r\n    let age = today.getFullYear() - birthDate.getFullYear();\r\n    const monthDiff = today.getMonth() - birthDate.getMonth();\r\n\r\n    if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {\r\n      age--;\r\n    }\r\n\r\n    if (age <= this.context.options.years) {\r\n      return VALID_RULE;\r\n    }\r\n\r\n    this.context.translationParams.years = this.context.options.years;\r\n\r\n    return invalidRule(this, context);\r\n  },\r\n};\r\n\r\n/**\r\n * Week day rule - date must be specific weekday\r\n */\r\nexport const weekDayRule: SchemaRule<{ day: WeekDay }> = {\r\n  name: \"weekDay\",\r\n  defaultErrorMessage: \"The :input must be a :day\",\r\n  async validate(value: Date, context) {\r\n    const inputDate = new Date(value);\r\n    const dayOfWeek = inputDate.getDay();\r\n    const expectedDay = WEEK_DAYS[this.context.options.day];\r\n\r\n    if (dayOfWeek === expectedDay) {\r\n      return VALID_RULE;\r\n    }\r\n\r\n    this.context.translatableParams.day = this.context.options.day;\r\n\r\n    return invalidRule(this, context);\r\n  },\r\n};\r\n"],"mappings":"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"}