{"version":3,"file":"index.modern.mjs","sources":["../src/utils.ts","../src/index.ts"],"sourcesContent":["import dayjs from \"dayjs\";\nimport utc from \"dayjs/plugin/utc\"; // dependent on utc plugin\nimport timezone from \"dayjs/plugin/timezone\";\nimport customParseFormat from \"dayjs/plugin/customParseFormat\";\nimport Holidays from \"date-holidays\";\nimport { CustomHoliday } from \"./types\";\n\ndayjs.extend(utc);\ndayjs.extend(timezone);\ndayjs.extend(customParseFormat);\n\n/**\n * Throws error to the console if a US State abbreviation is invalid, otherwise returns true\n *\n * @param {string} stateAbbrv: State abbreviation. eg \"pa\"\n * @param {Holidays} hd: date-holidays instance\n * @returns {boolean} returns true if valid US state\n */\nexport const validateState = (stateAbbrv: string, hd: Holidays): boolean => {\n  let stateList = Object.keys(hd.getStates(\"US\"));\n  stateList = [...stateList, \"US\", \"USA\"];\n  const stateInList = stateList.includes(stateAbbrv.toUpperCase());\n  if (!stateInList) {\n    throw `${stateAbbrv} is not a US state.`;\n  }\n  return true;\n};\n\n/**\n * Checks that provided date is in valid format and returns date as a dayjs object.\n *\n * @param {string| Date | dayjs.Dayjs} inputDate - date to validate\n * @returns {Dayjs} inputDate converted into Dayjs object.\n */\nexport const validateDate = (inputDate: string| Date | dayjs.Dayjs): dayjs.Dayjs => {\n  try {\n    inputDate = dayjs.tz(inputDate, \"YYYY-MM-DD\", \"America/New_York\");\n  } catch (e) {\n    throw (\n      (\"Could not parse date. Please provide either a dayjs object, native Date object, or a string formatted as 'YYYY-MM-DD'\")\n    );\n  }\n  return inputDate;\n};\n\n/**\n * Gets the date-holiday defined 'rule' for a specific holiday. Returns empty string if name isn't found.\n *\n * @param {Holidays} hd - Holidays instance\n * @param {string} holName - name of holiday. eg. \"Christmas Day\"\n * @param {string | number | Date} year - year to search, defaults to current year if not provided.\n * @returns {string}\n */\nexport const getHolidayRule = (hd: Holidays, holName: string, year?: string | number | Date): string => {\n  const holList = hd.getHolidays(year);\n  const hol = holList.find((item) => {\n    return item.name.toLowerCase() === holName.toLowerCase();\n  });\n  if (hol) {\n    return hol.rule;\n  }\n  return \"\";\n};\n\n/**\n * Takes a Holidays instance and list of holidays and sets each holiday's type as 'optional' in the instance.\n * \n * @param {Holidays} hd - Holidays instance\n * @param {string[]} arrHols - array of holiday names. eg [\"Christmas Day\", \"New Year's Day\"]\n * @param {string | number | Date} year - year to search, defaults to current year if not provided.\n * @returns {void} \n */\nexport const filterHolidays = (hd: Holidays, arrHols: string[], year?: string | number | Date): void => {\n  arrHols.forEach((holName) => {\n    const rule = getHolidayRule(hd, holName, year);\n    if (rule) {\n      hd.setHoliday(rule, { name: holName, type: \"optional\" });\n    }\n  });\n};\n\n/**\n * Takes a Holidays instance and adds a list of custom public holidays.\n * \n * @param {Holidays} hd - Holidays instance\n * @param {CustomHoliday[]} arrHols - list of objects representing custom holidays.\n * @returns {void} \n */\nexport const addPublicHolidays = (hd: Holidays, arrHols: CustomHoliday[]): void => {\n  arrHols.forEach(({ rule, name }) => {\n    if (rule && name) {\n      hd.setHoliday(rule, { name, type: \"public\" });\n    } else {\n      throw \"Custom holidays must include a rule and a name\";\n    }\n  });\n};\n","import Holidays from \"date-holidays\";\nimport dayjs from \"dayjs\";\nimport {\n  validateState,\n  validateDate,\n  filterHolidays,\n  addPublicHolidays,\n} from \"./utils\";\n\n/**\n * Factory function that creates a businessDays object.\n *\n * @param {string} options.state – U.S. state to determine holidays. Eg. \"pa\". Defaults to \"USA\"\n * @param {Array} options.excludeHolidays – list of strings with holiday names to exclude from being considered as non-business days.\n * @returns {businessDays} businessDays object\n */\nconst businessDays = ({\n  state = \"US\",\n  excludeHolidays = [],\n  addHolidays = [],\n} = {}) => {\n  const hd = new Holidays();\n  validateState(state, hd);\n  const cleanUSState = state.toUpperCase();\n  if (cleanUSState === \"US\" || cleanUSState === \"USA\") {\n    hd.init(\"US\");\n  } else {\n    hd.init(\"US\", cleanUSState);\n  }\n  if (excludeHolidays.length > 0) {\n    filterHolidays(hd, excludeHolidays);\n  }\n  if (addHolidays.length > 0) {\n    addPublicHolidays(hd, addHolidays);\n  }\n  return {\n    hd,\n    USState: cleanUSState,\n    /**\n     * Returns an array of all public holidays for a given year. \n     *\n     * @param {string | number | Date} year – year to get holidays for. Defaults to current year if not provided.\n     * @returns {Array}\n     */\n    getHolidays(year?: string | number | Date) {\n      const publicHols = this.hd\n        .getHolidays(year)\n        .filter((item) => item.type === \"public\");\n      return publicHols;\n      // const publicHols = hols.filter(item => item.type === \"public\")\n      // return publicHols;\n    },\n    /**\n     * Returns false if input date is on a weekend or a public holiday in Pennsylvania, USA.\n     *\n     * @param {string | Date | dayjs.Dayjs} inputDate - date to check.\n     * @returns {bool} true if inputDate is a weekend or holiday\n     */\n    check(inputDate: string | Date | dayjs.Dayjs) {\n      const dayJsObj: dayjs.Dayjs = validateDate(inputDate);\n      // Check if Sun (0) or Sat (6)\n      const dayOfWeek = dayJsObj.day();\n      if (dayOfWeek === 0 || dayOfWeek === 6) {\n        return false;\n      }\n      // Check if public holiday or substitute public holiday\n      const holidayArr = this.hd.isHoliday(dayJsObj.toDate());\n      if (holidayArr && holidayArr[0].type === \"public\") {\n        return false;\n      }\n      return true;\n    },\n    /**\n     * Adds business days to a date and returns a new date as a DayJS object. First date is excluded from count by default.\n     *\n     * @param {string | Date | dayjs.Dayjs} inputDate - a date to begin calculation from.\n     * @param {number} days - number of days to add to inputDate\n     * @param {bool} [options.excludeInitialDate=true] - whether to exclude the first date when adding.\n     * @returns {dayjs}\n     */\n    addDays(inputDate: string | Date | dayjs.Dayjs, days: number, { excludeInitialDate = true } = {}) {\n      let counter = 0;\n      let dayJsObj: dayjs.Dayjs = validateDate(inputDate);\n      if (excludeInitialDate) {\n        dayJsObj = dayJsObj.add(1, \"day\");\n      }\n      while (counter < days) {\n        if (this.check(dayJsObj)) {\n          counter++;\n        }\n        if (counter < days) {\n          dayJsObj = dayJsObj.add(1, \"day\");\n        }\n      }\n      return dayJsObj;\n    },\n    /**\n     * Returns an object with a tally of the number of business days, weekend days, and public holidays between two dates. First date is excluded from count by default.\n     *\n     * @param {string | Date | dayjs.Dayjs} dateStart - a date to begin calculation from.\n     * @param {string | Date | dayjs.Dayjs} dateEnd - a date to begin calculation from.\n     * @param {bool} [options.excludeInitialDate=true] - whether to exclude the first date when adding.\n     * @returns {dayjs}\n     */\n    countDays(dateStart: string | Date | dayjs.Dayjs, dateEnd: string | Date | dayjs.Dayjs, { excludeInitialDate = true } = {}) {\n      const dayJsStart: dayjs.Dayjs = validateDate(dateStart);\n      const dayJsEnd: dayjs.Dayjs = validateDate(dateEnd);\n      if (dayJsStart.isAfter(dateEnd)) {\n        throw `${dateStart} is after ${dateEnd}. Provide a start date that is earlier than end date in order to calculate days between`;\n      }\n      let totalDays = 0;\n      let holidays = 0;\n      let holidayList = [];\n      let weekendDays = 0;\n      let weekdays = 0;\n      let holidaysOnWeekends = 0;\n      let businessDays = 0;\n      let dateCounter = dayJsStart.clone();\n      if (excludeInitialDate) {\n        dateCounter = dayJsStart.add(1, \"day\");\n      }\n      while (!dateCounter.isSame(dayJsEnd.add(1, \"day\"), \"day\")) {\n        totalDays++;\n        const holidayArr = this.hd.isHoliday(dateCounter.toDate());\n        const dayOfWeek = dateCounter.day();\n        if (holidayArr && holidayArr[0].type === \"public\") {\n          holidays++;\n          holidayList.push(holidayArr[0]);\n        }\n        if ((dayOfWeek === 0) || (dayOfWeek === 6)) {\n          weekendDays++;\n        }\n        if (!((dayOfWeek === 0) || (dayOfWeek === 6))) {\n          weekdays++;\n        }\n        if (\n          ((dayOfWeek === 0) || (dayOfWeek === 6)) &&\n          (holidayArr &&\n          holidayArr[0].type === \"public\")\n        ) {\n          holidaysOnWeekends++;\n        }\n        if (\n          !((dayOfWeek === 0) || (dayOfWeek === 6)) &&\n          !(holidayArr && holidayArr[0].type === \"public\")\n        ) {\n          businessDays++;\n        }\n        dateCounter = dateCounter.add(1, \"day\");\n      }\n      return {\n        totalDays,\n        holidays,\n        holidayList,\n        weekdays,\n        weekendDays,\n        holidaysOnWeekends,\n        businessDays,\n        nonBusinessDays: totalDays - businessDays,\n      };\n    },\n  };\n};\nexport default businessDays;\n"],"names":["dayjs","extend","utc","timezone","customParseFormat","validateDate","inputDate","tz","e","businessDays","state","excludeHolidays","addHolidays","hd","Holidays","validateState","stateAbbrv","stateList","Object","keys","getStates","includes","toUpperCase","cleanUSState","init","length","filterHolidays","arrHols","year","forEach","holName","rule","getHolidayRule","hol","getHolidays","find","item","name","toLowerCase","setHoliday","type","addPublicHolidays","USState","this","filter","check","dayJsObj","dayOfWeek","day","holidayArr","isHoliday","toDate","addDays","days","excludeInitialDate","counter","add","countDays","dateStart","dateEnd","dayJsStart","dayJsEnd","isAfter","totalDays","holidays","holidayList","weekendDays","weekdays","holidaysOnWeekends","dateCounter","clone","isSame","push","nonBusinessDays"],"mappings":"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"}