1{"version":3,"file":"scheduleNotificationAsync.js","sourceRoot":"","sources":["../src/scheduleNotificationAsync.ts"],"names":[],"mappings":"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","sourcesContent":["import { Platform, UnavailabilityError } from 'expo-modules-core';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport NotificationScheduler from './NotificationScheduler';\nimport { NotificationTriggerInput as NativeNotificationTriggerInput } from './NotificationScheduler.types';\nimport {\n  NotificationRequestInput,\n  NotificationTriggerInput,\n  DailyTriggerInput,\n  WeeklyTriggerInput,\n  YearlyTriggerInput,\n  CalendarTriggerInput,\n  TimeIntervalTriggerInput,\n  DateTriggerInput,\n  ChannelAwareTriggerInput,\n  SchedulableNotificationTriggerInput,\n} from './Notifications.types';\n\n/**\n * Schedules a notification to be triggered in the future.\n * > **Note:** Please note that this does not mean that the notification will be presented when it is triggered.\n * For the notification to be presented you have to set a notification handler with [`setNotificationHandler`](#notificationssetnotificationhandlerhandler)\n * that will return an appropriate notification behavior. For more information see the example below.\n * @param request An object describing the notification to be triggered.\n * @return Returns a Promise resolving to a string which is a notification identifier you can later use to cancel the notification or to identify an incoming notification.\n * @example\n * # Schedule the notification that will trigger once, in one minute from now\n * ```ts\n * import * as Notifications from 'expo-notifications';\n *\n * Notifications.scheduleNotificationAsync({\n *   content: {\n *     title: \"Time's up!\",\n *     body: 'Change sides!',\n *   },\n *   trigger: {\n *     seconds: 60,\n *   },\n * });\n * ```\n *\n * # Schedule the notification that will trigger repeatedly, every 20 minutes\n * ```ts\n * import * as Notifications from 'expo-notifications';\n *\n * Notifications.scheduleNotificationAsync({\n *   content: {\n *     title: 'Remember to drink water!',\n *   },\n *   trigger: {\n *     seconds: 60 * 20,\n *     repeats: true,\n *   },\n * });\n * ```\n *\n * # Schedule the notification that will trigger once, at the beginning of next hour\n * ```ts\n * import * as Notifications from 'expo-notifications';\n *\n * const trigger = new Date(Date.now() + 60 * 60 * 1000);\n * trigger.setMinutes(0);\n * trigger.setSeconds(0);\n *\n * Notifications.scheduleNotificationAsync({\n *   content: {\n *     title: 'Happy new hour!',\n *   },\n *   trigger,\n * });\n * ```\n * @header schedule\n */\nexport default async function scheduleNotificationAsync(\n  request: NotificationRequestInput\n): Promise<string> {\n  if (!NotificationScheduler.scheduleNotificationAsync) {\n    throw new UnavailabilityError('Notifications', 'scheduleNotificationAsync');\n  }\n\n  return await NotificationScheduler.scheduleNotificationAsync(\n    request.identifier ?? uuidv4(),\n    request.content,\n    parseTrigger(request.trigger)\n  );\n}\n\ntype ValidTriggerDateComponents = 'month' | 'day' | 'weekday' | 'hour' | 'minute';\n\nconst DAILY_TRIGGER_EXPECTED_DATE_COMPONENTS: readonly ValidTriggerDateComponents[] = [\n  'hour',\n  'minute',\n];\nconst WEEKLY_TRIGGER_EXPECTED_DATE_COMPONENTS: readonly ValidTriggerDateComponents[] = [\n  'weekday',\n  'hour',\n  'minute',\n];\nconst YEARLY_TRIGGER_EXPECTED_DATE_COMPONENTS: readonly ValidTriggerDateComponents[] = [\n  'day',\n  'month',\n  'hour',\n  'minute',\n];\n\nexport function parseTrigger(\n  userFacingTrigger: NotificationTriggerInput\n): NativeNotificationTriggerInput {\n  if (userFacingTrigger === null) {\n    return null;\n  }\n\n  if (userFacingTrigger === undefined) {\n    throw new TypeError(\n      'Encountered an `undefined` notification trigger. If you want to trigger the notification immediately, pass in an explicit `null` value.'\n    );\n  }\n\n  if (isDateTrigger(userFacingTrigger)) {\n    return parseDateTrigger(userFacingTrigger);\n  } else if (isDailyTriggerInput(userFacingTrigger)) {\n    validateDateComponentsInTrigger(userFacingTrigger, DAILY_TRIGGER_EXPECTED_DATE_COMPONENTS);\n    return {\n      type: 'daily',\n      channelId: userFacingTrigger.channelId,\n      hour: userFacingTrigger.hour,\n      minute: userFacingTrigger.minute,\n    };\n  } else if (isWeeklyTriggerInput(userFacingTrigger)) {\n    validateDateComponentsInTrigger(userFacingTrigger, WEEKLY_TRIGGER_EXPECTED_DATE_COMPONENTS);\n    return {\n      type: 'weekly',\n      channelId: userFacingTrigger.channelId,\n      weekday: userFacingTrigger.weekday,\n      hour: userFacingTrigger.hour,\n      minute: userFacingTrigger.minute,\n    };\n  } else if (isYearlyTriggerInput(userFacingTrigger)) {\n    validateDateComponentsInTrigger(userFacingTrigger, YEARLY_TRIGGER_EXPECTED_DATE_COMPONENTS);\n    return {\n      type: 'yearly',\n      channelId: userFacingTrigger.channelId,\n      day: userFacingTrigger.day,\n      month: userFacingTrigger.month,\n      hour: userFacingTrigger.hour,\n      minute: userFacingTrigger.minute,\n    };\n  } else if (isSecondsPropertyMisusedInCalendarTriggerInput(userFacingTrigger)) {\n    throw new TypeError(\n      'Could not have inferred the notification trigger type: if you want to use a time interval trigger, pass in only `seconds` with or without `repeats` property; if you want to use calendar-based trigger, pass in `second`.'\n    );\n  } else if ('seconds' in userFacingTrigger) {\n    return {\n      type: 'timeInterval',\n      channelId: userFacingTrigger.channelId,\n      seconds: userFacingTrigger.seconds,\n      repeats: userFacingTrigger.repeats ?? false,\n    };\n  } else if (isCalendarTrigger(userFacingTrigger)) {\n    const { repeats, ...calendarTrigger } = userFacingTrigger;\n    return { type: 'calendar', value: calendarTrigger, repeats };\n  } else {\n    return Platform.select({\n      default: null, // There's no notion of channels on platforms other than Android.\n      android: { type: 'channel', channelId: userFacingTrigger.channelId },\n    });\n  }\n}\n\nfunction isCalendarTrigger(\n  trigger: CalendarTriggerInput | ChannelAwareTriggerInput\n): trigger is CalendarTriggerInput {\n  const { channelId, ...triggerWithoutChannelId } = trigger;\n  return Object.keys(triggerWithoutChannelId).length > 0;\n}\n\nfunction isDateTrigger(\n  trigger:\n    | DateTriggerInput\n    | WeeklyTriggerInput\n    | DailyTriggerInput\n    | CalendarTriggerInput\n    | TimeIntervalTriggerInput\n): trigger is DateTriggerInput {\n  return (\n    trigger instanceof Date ||\n    typeof trigger === 'number' ||\n    (typeof trigger === 'object' && 'date' in trigger)\n  );\n}\n\nfunction parseDateTrigger(trigger: DateTriggerInput): NativeNotificationTriggerInput {\n  if (trigger instanceof Date || typeof trigger === 'number') {\n    return { type: 'date', timestamp: toTimestamp(trigger) };\n  }\n  return { type: 'date', timestamp: toTimestamp(trigger.date), channelId: trigger.channelId };\n}\n\nfunction toTimestamp(date: number | Date) {\n  if (date instanceof Date) {\n    return date.getTime();\n  }\n  return date;\n}\n\nfunction isDailyTriggerInput(\n  trigger: SchedulableNotificationTriggerInput\n): trigger is DailyTriggerInput {\n  if (typeof trigger !== 'object') return false;\n  const { channelId, ...triggerWithoutChannelId } = trigger as DailyTriggerInput;\n  return (\n    Object.keys(triggerWithoutChannelId).length ===\n      DAILY_TRIGGER_EXPECTED_DATE_COMPONENTS.length + 1 &&\n    DAILY_TRIGGER_EXPECTED_DATE_COMPONENTS.every(\n      (component) => component in triggerWithoutChannelId\n    ) &&\n    'repeats' in triggerWithoutChannelId &&\n    triggerWithoutChannelId.repeats === true\n  );\n}\n\nfunction isWeeklyTriggerInput(\n  trigger: SchedulableNotificationTriggerInput\n): trigger is WeeklyTriggerInput {\n  if (typeof trigger !== 'object') return false;\n  const { channelId, ...triggerWithoutChannelId } = trigger as WeeklyTriggerInput;\n  return (\n    Object.keys(triggerWithoutChannelId).length ===\n      WEEKLY_TRIGGER_EXPECTED_DATE_COMPONENTS.length + 1 &&\n    WEEKLY_TRIGGER_EXPECTED_DATE_COMPONENTS.every(\n      (component) => component in triggerWithoutChannelId\n    ) &&\n    'repeats' in triggerWithoutChannelId &&\n    triggerWithoutChannelId.repeats === true\n  );\n}\n\nfunction isYearlyTriggerInput(\n  trigger: SchedulableNotificationTriggerInput\n): trigger is YearlyTriggerInput {\n  if (typeof trigger !== 'object') return false;\n  const { channelId, ...triggerWithoutChannelId } = trigger as YearlyTriggerInput;\n  return (\n    Object.keys(triggerWithoutChannelId).length ===\n      YEARLY_TRIGGER_EXPECTED_DATE_COMPONENTS.length + 1 &&\n    YEARLY_TRIGGER_EXPECTED_DATE_COMPONENTS.every(\n      (component) => component in triggerWithoutChannelId\n    ) &&\n    'repeats' in triggerWithoutChannelId &&\n    triggerWithoutChannelId.repeats === true\n  );\n}\n\nfunction isSecondsPropertyMisusedInCalendarTriggerInput(\n  trigger: TimeIntervalTriggerInput | CalendarTriggerInput\n) {\n  const { channelId, ...triggerWithoutChannelId } = trigger;\n  return (\n    // eg. { seconds: ..., repeats: ..., hour: ... }\n    ('seconds' in triggerWithoutChannelId &&\n      'repeats' in triggerWithoutChannelId &&\n      Object.keys(triggerWithoutChannelId).length > 2) ||\n    // eg. { seconds: ..., hour: ... }\n    ('seconds' in triggerWithoutChannelId &&\n      !('repeats' in triggerWithoutChannelId) &&\n      Object.keys(triggerWithoutChannelId).length > 1)\n  );\n}\n\nfunction validateDateComponentsInTrigger(\n  trigger: NonNullable<NotificationTriggerInput>,\n  components: readonly ValidTriggerDateComponents[]\n) {\n  const anyTriggerType = trigger as any;\n  components.forEach((component) => {\n    if (!(component in anyTriggerType)) {\n      throw new TypeError(`The ${component} parameter needs to be present`);\n    }\n    if (typeof anyTriggerType[component] !== 'number') {\n      throw new TypeError(`The ${component} parameter should be a number`);\n    }\n    switch (component) {\n      case 'month': {\n        const { month } = anyTriggerType;\n        if (month < 0 || month > 11) {\n          throw new RangeError(`The month parameter needs to be between 0 and 11. Found: ${month}`);\n        }\n        break;\n      }\n      case 'day': {\n        const { day, month } = anyTriggerType;\n        const daysInGivenMonth = daysInMonth(month);\n        if (day < 1 || day > daysInGivenMonth) {\n          throw new RangeError(\n            `The day parameter for month ${month} must be between 1 and ${daysInGivenMonth}. Found: ${day}`\n          );\n        }\n        break;\n      }\n      case 'weekday': {\n        const { weekday } = anyTriggerType;\n        if (weekday < 1 || weekday > 7) {\n          throw new RangeError(\n            `The weekday parameter needs to be between 1 and 7. Found: ${weekday}`\n          );\n        }\n        break;\n      }\n      case 'hour': {\n        const { hour } = anyTriggerType;\n        if (hour < 0 || hour > 23) {\n          throw new RangeError(`The hour parameter needs to be between 0 and 23. Found: ${hour}`);\n        }\n        break;\n      }\n      case 'minute': {\n        const { minute } = anyTriggerType;\n        if (minute < 0 || minute > 59) {\n          throw new RangeError(\n            `The minute parameter needs to be between 0 and 59. Found: ${minute}`\n          );\n        }\n        break;\n      }\n    }\n  });\n}\n\n/**\n * Determines the number of days in the given month (or January if omitted).\n * If year is specified, it will include leap year logic, else it will always assume a leap year\n */\nfunction daysInMonth(month: number = 0, year?: number) {\n  return new Date(year ?? 2000, month + 1, 0).getDate();\n}\n"]}