{"version":3,"sources":["../src/errors.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["export class ChronoBoxError extends Error {\n  constructor(message: string) {\n    super(message);\n    this.name = \"ChronoBoxError\";\n  }\n}\n","import { TimeUnit } from \"./enums\";\n\nexport const isValidTimeUnit = (unit: any): unit is TimeUnit =>\n  unit === TimeUnit.MILLISECONDS ||\n  unit === TimeUnit.SECONDS ||\n  unit === TimeUnit.MINUTES ||\n  unit === TimeUnit.HOURS ||\n  unit === TimeUnit.DAYS ||\n  unit === TimeUnit.WEEKS ||\n  unit === TimeUnit.MONTHS ||\n  unit === TimeUnit.YEARS;\n","import type { CustomFormat, DateComponents, DateInput } from \"./types.d.ts\";\n\nimport { ChronoBoxError } from \"./errors\";\nimport { isValidTimeUnit } from \"./utils\";\nimport { DateFormat, TimeUnit } from \"./enums\";\n\nexport class ChronoBox<TFormat extends DateFormat | CustomFormat = DateFormat> {\n  private readonly date: Date;\n  private readonly format: TFormat;\n\n  constructor(date?: DateInput, format: TFormat = DateFormat.ISO as TFormat) {\n    this.format = format;\n\n    try {\n      this.date = date ? new Date(date) : new Date();\n      if (isNaN(this.date.getTime())) {\n        throw new ChronoBoxError(\"Invalid date input\");\n      }\n    } catch (error) {\n      throw new ChronoBoxError(\n        `Failed to parse date: ${\n          error instanceof Error ? error.message : \"Unknown error\"\n        }`\n      );\n    }\n  }\n\n  /**\n   * Add a specified amount of time units to the date\n   */\n  add<T extends TimeUnit>(amount: number, unit: T): ChronoBox<TFormat> {\n    const newDate = new Date(this.date);\n\n    switch (unit) {\n      case TimeUnit.MILLISECONDS:\n        newDate.setMilliseconds(newDate.getMilliseconds() + amount);\n        break;\n      case TimeUnit.SECONDS:\n        newDate.setSeconds(newDate.getSeconds() + amount);\n        break;\n      case TimeUnit.MINUTES:\n        newDate.setMinutes(newDate.getMinutes() + amount);\n        break;\n      case TimeUnit.HOURS:\n        newDate.setHours(newDate.getHours() + amount);\n        break;\n      case TimeUnit.DAYS:\n        newDate.setDate(newDate.getDate() + amount);\n        break;\n      case TimeUnit.WEEKS:\n        newDate.setDate(newDate.getDate() + amount * 7);\n        break;\n      case TimeUnit.MONTHS: {\n        const dayOfMonth = newDate.getDate();\n        newDate.setDate(1); // Temporarily set to the first of the month\n        newDate.setMonth(newDate.getMonth() + amount);\n        const maxDaysInNewMonth = new Date(\n          newDate.getFullYear(),\n          newDate.getMonth() + 1,\n          0\n        ).getDate();\n        newDate.setDate(Math.min(dayOfMonth, maxDaysInNewMonth));\n        break;\n      }\n      case TimeUnit.YEARS: {\n        const dayOfMonth = newDate.getDate();\n        newDate.setDate(1); // Temporarily set to the first of the month\n        newDate.setFullYear(newDate.getFullYear() + amount);\n        const maxDaysInNewMonth = new Date(\n          newDate.getFullYear(),\n          newDate.getMonth() + 1,\n          0\n        ).getDate();\n        newDate.setDate(Math.min(dayOfMonth, maxDaysInNewMonth));\n        break;\n      }\n      default:\n        const _exhaustiveCheck: never = unit;\n        throw new ChronoBoxError(`Unsupported time unit: ${unit}`);\n    }\n\n    return new ChronoBox<TFormat>(newDate, this.format);\n  }\n\n  /**\n   * Subtract a specified amount of time units from the date\n   */\n  subtract<T extends TimeUnit>(amount: number, unit: T): ChronoBox<TFormat> {\n    return this.add(-amount, unit);\n  }\n\n  /**\n   * Get the difference between two dates in the specified unit\n   */\n  diff(other: DateInput, unit: TimeUnit = TimeUnit.DAYS): number {\n    const otherDate = new Date(other);\n    const diffMs = this.date.getTime() - otherDate.getTime();\n\n    if (!isValidTimeUnit(unit)) {\n      throw new ChronoBoxError(`Unsupported time unit: ${unit}`);\n    }\n\n    switch (unit) {\n      case TimeUnit.MILLISECONDS:\n        return diffMs;\n      case TimeUnit.SECONDS:\n        return diffMs / 1000;\n      case TimeUnit.MINUTES:\n        return diffMs / (1000 * 60);\n      case TimeUnit.HOURS:\n        return diffMs / (1000 * 60 * 60);\n      case TimeUnit.DAYS:\n        return diffMs / (1000 * 60 * 60 * 24);\n      case TimeUnit.WEEKS:\n        return diffMs / (1000 * 60 * 60 * 24 * 7);\n      case TimeUnit.MONTHS:\n        return (\n          (this.date.getFullYear() - otherDate.getFullYear()) * 12 +\n          (this.date.getMonth() - otherDate.getMonth())\n        );\n      case TimeUnit.YEARS:\n        return this.date.getFullYear() - otherDate.getFullYear();\n      default:\n        const _exhaustiveCheck: never = unit;\n        throw new ChronoBoxError(`Unsupported time unit: ${unit}`);\n    }\n  }\n\n  /**\n   * Get individual components of the date\n   */\n  getComponents(): DateComponents {\n    return {\n      year: this.date.getFullYear(),\n      month: this.date.getMonth() + 1,\n      day: this.date.getDate(),\n      hours: this.date.getHours(),\n      minutes: this.date.getMinutes(),\n      seconds: this.date.getSeconds(),\n      milliseconds: this.date.getMilliseconds(),\n    };\n  }\n\n  /**\n   * Format the date according to the format string\n   */\n  formatDate(): string {\n    const components = this.getComponents();\n    const monthNames = [\n      \"January\",\n      \"February\",\n      \"March\",\n      \"April\",\n      \"May\",\n      \"June\",\n      \"July\",\n      \"August\",\n      \"September\",\n      \"October\",\n      \"November\",\n      \"December\",\n    ];\n\n    let result = this.format;\n\n    // Replace tokens with actual values\n    return result\n      .replace(\"YYYY\", components.year.toString())\n      .replace(\"MMMM\", monthNames[components.month - 1])\n      .replace(\"MM\", components.month.toString().padStart(2, \"0\"))\n      .replace(\"DD\", components.day.toString().padStart(2, \"0\"));\n  }\n\n  /**\n   * Check if the date is valid\n   */\n  isValid(): boolean {\n    return !isNaN(this.date.getTime());\n  }\n\n  /**\n   * Get the underlying Date object\n   */\n  toDate(): Date {\n    return new Date(this.date);\n  }\n\n  /**\n   * Create a new ChronoBox with a different format\n   */\n  withFormat<NewFormat extends DateFormat | CustomFormat>(\n    newFormat: NewFormat\n  ): ChronoBox<NewFormat> {\n    return new ChronoBox<NewFormat>(this.date, newFormat);\n  }\n}\n"],"mappings":"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","names":[]}