90dc-core 1.6.0 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/lib/dbmodels/DeviceTokens.d.ts +6 -0
  2. package/dist/lib/dbmodels/DeviceTokens.js +34 -0
  3. package/dist/lib/dbmodels/DeviceTokens.js.map +1 -0
  4. package/dist/lib/dbmodels/NotificationModels.d.ts +8 -0
  5. package/dist/lib/dbmodels/NotificationModels.js +38 -0
  6. package/dist/lib/dbmodels/NotificationModels.js.map +1 -0
  7. package/dist/lib/dbmodels/TranslatedNotification.d.ts +9 -0
  8. package/dist/lib/dbmodels/TranslatedNotification.js +45 -0
  9. package/dist/lib/dbmodels/TranslatedNotification.js.map +1 -0
  10. package/dist/lib/dbmodels/program/ThirtyDayChallenge.d.ts +13 -0
  11. package/dist/lib/dbmodels/program/ThirtyDayChallenge.js +70 -0
  12. package/dist/lib/dbmodels/program/ThirtyDayChallenge.js.map +1 -0
  13. package/dist/lib/dbmodels/program/ThirtyDayChallengeStrengthTest.d.ts +11 -0
  14. package/dist/lib/dbmodels/program/ThirtyDayChallengeStrengthTest.js +55 -0
  15. package/dist/lib/dbmodels/program/ThirtyDayChallengeStrengthTest.js.map +1 -0
  16. package/dist/lib/enums/ProgramTemplates.d.ts +8 -0
  17. package/dist/lib/enums/ProgramTemplates.js +738 -0
  18. package/dist/lib/enums/ProgramTemplates.js.map +1 -0
  19. package/dist/lib/enums/cert.d.ts +13 -0
  20. package/dist/lib/enums/cert.js +15 -0
  21. package/dist/lib/enums/cert.js.map +1 -0
  22. package/dist/lib/models/NotificationInterfaces.d.ts +50 -0
  23. package/dist/lib/models/NotificationInterfaces.js +11 -0
  24. package/dist/lib/models/NotificationInterfaces.js.map +1 -0
  25. package/dist/lib/utils/NotificationsUtil.d.ts +14 -0
  26. package/dist/lib/utils/NotificationsUtil.js +147 -0
  27. package/dist/lib/utils/NotificationsUtil.js.map +1 -0
  28. package/package.json +4 -1
  29. package/src/lib/dbmodels/DeviceTokens.ts +24 -0
  30. package/src/lib/dbmodels/NotificationModels.ts +39 -0
  31. package/src/lib/dbmodels/TranslatedNotification.ts +42 -0
  32. package/src/lib/dbmodels/program/ThirtyDayChallenge.ts +46 -0
  33. package/src/lib/dbmodels/program/ThirtyDayChallengeStrengthTest.ts +39 -0
  34. package/src/lib/enums/ProgramTemplates.ts +881 -0
  35. package/src/lib/enums/cert.ts +16 -0
  36. package/src/lib/models/NotificationInterfaces.ts +66 -0
  37. package/src/lib/utils/NotificationsUtil.ts +188 -0
  38. package/tsconfig.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/lib/enums/ProgramTemplates.ts"],"sourcesContent":["export const ThreeDaysTemplate = [\n\t'StrengthTest',\n\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\t'Rest',\n\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\t'Rest',\n\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\t'Rest',\n\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\t'Rest',\n\n\t'StrengthTest',\n\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\t'Rest',\n\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\t'Rest',\n\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\t'Rest',\n\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\t'Rest',\n\n\t'Workout',\n\n\t'StrengthTest',\n\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\t'Rest',\n\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\t'Rest',\n\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\t'Rest',\n\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\t'Rest',\n\n\t'Workout',\n\t'Rest',\n\n\t'StrengthTest'\n];\n\nexport const FourDaysTemplate = [\n\t'StrengthTest',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\n\t'StrengthTest',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\n\t'StrengthTest',\n\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Rest',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\n\t'StrengthTest'\n];\n\nexport const FourDaysBodyWeightTemplate = [\n\t'StrengthTest',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Rest',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Rest',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Rest',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Rest',\n\t'Challenge',\n\n\t'StrengthTest',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Rest',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Rest',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Rest',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Rest',\n\t'Challenge',\n\n\t'Workout',\n\n\t'StrengthTest',\n\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Rest',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Rest',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Rest',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Rest',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\n\t'StrengthTest'\n];\n\nexport const FiveDaysTemplate = [\n\t'StrengthTest',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'StrengthTest',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\n\t'StrengthTest',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\n\t'StrengthTest'\n];\n\nexport const FiveDaysHomeWorkoutTemplate = [\n\t'StrengthTest',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Challenge',\n\n\t'StrengthTest',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\n\t'StrengthTest',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\n\t'StrengthTest'\n];\n\nexport const FiveDaysBodyWeightTemplate = [\n\t'StrengthTest',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'StrengthTest',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\n\t'StrengthTest',\n\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\n\t'StrengthTest'\n];\n\nexport const SixDaysTemplate = [\n\t'StrengthTest',\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'StrengthTest',\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\n\t'StrengthTest',\n\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\n\t'StrengthTest'\n];\n\nexport const SixDaysHomeWorkoutTemplate = [\n\t'StrengthTest',\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'StrengthTest',\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\n\t'StrengthTest',\n\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\t'MergedWorkout',\n\t'Workout',\n\t'Workout',\n\t'Workout',\n\t'Challenge',\n\n\t'Workout',\n\t'Workout',\n\n\t'StrengthTest'\n];"],"names":["ThreeDaysTemplate","FourDaysTemplate","FourDaysBodyWeightTemplate","FiveDaysTemplate","FiveDaysHomeWorkoutTemplate","FiveDaysBodyWeightTemplate","SixDaysTemplate","SixDaysHomeWorkoutTemplate"],"mappings":"AAAA,OAAO,MAAMA,oBAAoB;IAChC;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IAEA;IAEA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IAEA;CACA,CAAC;AAEF,OAAO,MAAMC,mBAAmB;IAC/B;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IAEA;IAEA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IAEA;CACA,CAAC;AAEF,OAAO,MAAMC,6BAA6B;IACzC;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IAEA;IAEA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IAEA;CACA,CAAC;AAEF,OAAO,MAAMC,mBAAmB;IAC/B;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IAEA;IAEA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IAEA;CACA,CAAC;AAEF,OAAO,MAAMC,8BAA8B;IAC1C;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IAEA;IAEA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IAEA;CACA,CAAC;AAEF,OAAO,MAAMC,6BAA6B;IACzC;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IAEA;IAEA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IAEA;CACA,CAAC;AAEF,OAAO,MAAMC,kBAAkB;IAC9B;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IAEA;IAEA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAGA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IAEA;CACA,CAAC;AAEF,OAAO,MAAMC,6BAA6B;IACzC;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IAEA;IAEA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAGA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IAEA;CACA,CAAC"}
@@ -0,0 +1,13 @@
1
+ export declare const cert_key: {
2
+ type: string;
3
+ project_id: string;
4
+ private_key_id: string;
5
+ private_key: string;
6
+ client_email: string;
7
+ client_id: string;
8
+ auth_uri: string;
9
+ token_uri: string;
10
+ auth_provider_x509_cert_url: string;
11
+ client_x509_cert_url: string;
12
+ universe_domain: string;
13
+ };
@@ -0,0 +1,15 @@
1
+ export const cert_key = {
2
+ type: "service_account",
3
+ project_id: "dayschallenge-373510",
4
+ private_key_id: "728533f268b61808b2566c1a26166db36b422f44",
5
+ private_key: "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDCvQREgqfl+hC+\nsoVNksqOI+IN1TxhhCzfwl/mb4TR+L09i7VcdN/vgQL/zDH6++31evKruqTBaLha\nOk2OZPUd29FXG3qxZJtKMxhKpyhw/NQjABHFQ4K2JDCk9VqDASve2M5JHp1YXzJb\n5rEap3RM+dHNxR37zWU0kfLSo8OBSrAj/DCsezd5QqXqt0aB2N4VjlEijm05z7Of\nJRTSUL+u1Ftt+ToSM2xih3AMMGMHhcqPjuZSWK6uVXG5Qo2SH11C1N5MX/qeACEB\n2wABJjrcMb+CmVzW+ZPkSeKFSuPk0390RodDvC6eZHCtM9ruhPJM7cvwlyxHhCUX\nu/bRRMyNAgMBAAECggEACH9ut2ig2AByCPL0WIlpImEUJQ4NjPnTas4/bhL8D5zp\nm80ZacKbNQctsNOMc3XZO/GUs6642sxtja5molSV0lWRzIR2oFVnZgpVwIg2fmZi\nAXGoKjIDJbHtl30yE8O80i7ReE+y27TdFzU5ZumGFzJ9l8ZGw9gCLGmZWDIXlBrb\nwo5t+sHc2JEGoh9XoLKPmyom1icVWAwZ4nnd774McbJkh8bfjgtz3DsVvBzAJu2R\n0phK4hq7ODqzV79iyhCRum2ETGLfPL437rTeJXjUGhk6V3je4Z6xmckLPoAMdiuR\nzVqBbdG1vUqb5lQEmLtIra5JTmZS5iBDQtqo5VQ+NwKBgQD+/JVzL0w3JAf2Cgte\nSIpe6P9hYZQDZqwNFNdefE2zxow+3rhB7e/zL/74fRdcAbdCXNXtZuO/GjpbIcRq\nUeKj7B7t8a28YIj53BDmOMzEFgbxOYkxcJGMSYiSidEdRRMOTTdVWnzPvzIVRipv\nZECAsn5ZaKazc+itWaS5evgxEwKBgQDDgyNRFWtPi7YFk1yp0BvZNOetJE2S4seT\nJzeMzkrhjzLFhS1OSv5NHAKGV1xRz95eaM8/sO7fOwPWaeTS5mu8/oQLIM8hdyW5\nAVg4VjRLHKPDBLLsFVur9QxxfLH68Pgypc0MIuIa2s8gbqNZXGqKbp7crhOJEDHo\ns245+zRf3wKBgAHJLRbIbwU32GJtwZSgd2+gvCEneMzpTC0vRy7fOgAXVOYf0zSL\nARI39NYyshYv4OOzGMB35wJwoZX/z4tbFXZGchUCi0/1cSAm3WtvXGfHK7dGyuIw\nwqQz46P7GR7WXALOoaOUZali0mv5uNRc5GLCXUYtCHXbSvbj2NZ/uPtHAoGAdnec\ny8H9zypp9gDv8hme9kNfaoOH2cw+gAUQXOqXZwudCSCEbl90rgad5QdEcnJRXMWH\nZyFv7KXW0nJB7CUg/Vj/a7rKp42JtwuAiEp7z1OgS0gqnnDmplCK5K1ZLyQaUJ40\nm/j7JqiVPyKrKjecextCeZelULUWeNlYnhuABeMCgYAiSHmLx8qm67kcOsSRsTxr\nU01s5jxlHFYz+no3ZxiS6fwvsuxppiFeqRYD/zUBOcFZ+tKPU/5hH2Icu43ZApZx\n0CwN2biiMKRMft8Wg8Lx5ZjS7il6roYPKHFlySQtoSoZXaHQLTMsW+wB+vUg5+YQ\nTBN30eKadMx9Ws8RgLKQ/A==\n-----END PRIVATE KEY-----\n",
6
+ client_email: "firebase-adminsdk-2yp4f@dayschallenge-373510.iam.gserviceaccount.com",
7
+ client_id: "104734701364860430708",
8
+ auth_uri: "https://accounts.google.com/o/oauth2/auth",
9
+ token_uri: "https://oauth2.googleapis.com/token",
10
+ auth_provider_x509_cert_url: "https://www.googleapis.com/oauth2/v1/certs",
11
+ client_x509_cert_url: "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-2yp4f%40dayschallenge-373510.iam.gserviceaccount.com",
12
+ universe_domain: "googleapis.com"
13
+ };
14
+
15
+ //# sourceMappingURL=cert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/lib/enums/cert.ts"],"sourcesContent":["export const cert_key = {\n type: \"service_account\",\n project_id: \"dayschallenge-373510\",\n private_key_id: \"728533f268b61808b2566c1a26166db36b422f44\",\n private_key:\n \"-----BEGIN PRIVATE KEY-----\\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDCvQREgqfl+hC+\\nsoVNksqOI+IN1TxhhCzfwl/mb4TR+L09i7VcdN/vgQL/zDH6++31evKruqTBaLha\\nOk2OZPUd29FXG3qxZJtKMxhKpyhw/NQjABHFQ4K2JDCk9VqDASve2M5JHp1YXzJb\\n5rEap3RM+dHNxR37zWU0kfLSo8OBSrAj/DCsezd5QqXqt0aB2N4VjlEijm05z7Of\\nJRTSUL+u1Ftt+ToSM2xih3AMMGMHhcqPjuZSWK6uVXG5Qo2SH11C1N5MX/qeACEB\\n2wABJjrcMb+CmVzW+ZPkSeKFSuPk0390RodDvC6eZHCtM9ruhPJM7cvwlyxHhCUX\\nu/bRRMyNAgMBAAECggEACH9ut2ig2AByCPL0WIlpImEUJQ4NjPnTas4/bhL8D5zp\\nm80ZacKbNQctsNOMc3XZO/GUs6642sxtja5molSV0lWRzIR2oFVnZgpVwIg2fmZi\\nAXGoKjIDJbHtl30yE8O80i7ReE+y27TdFzU5ZumGFzJ9l8ZGw9gCLGmZWDIXlBrb\\nwo5t+sHc2JEGoh9XoLKPmyom1icVWAwZ4nnd774McbJkh8bfjgtz3DsVvBzAJu2R\\n0phK4hq7ODqzV79iyhCRum2ETGLfPL437rTeJXjUGhk6V3je4Z6xmckLPoAMdiuR\\nzVqBbdG1vUqb5lQEmLtIra5JTmZS5iBDQtqo5VQ+NwKBgQD+/JVzL0w3JAf2Cgte\\nSIpe6P9hYZQDZqwNFNdefE2zxow+3rhB7e/zL/74fRdcAbdCXNXtZuO/GjpbIcRq\\nUeKj7B7t8a28YIj53BDmOMzEFgbxOYkxcJGMSYiSidEdRRMOTTdVWnzPvzIVRipv\\nZECAsn5ZaKazc+itWaS5evgxEwKBgQDDgyNRFWtPi7YFk1yp0BvZNOetJE2S4seT\\nJzeMzkrhjzLFhS1OSv5NHAKGV1xRz95eaM8/sO7fOwPWaeTS5mu8/oQLIM8hdyW5\\nAVg4VjRLHKPDBLLsFVur9QxxfLH68Pgypc0MIuIa2s8gbqNZXGqKbp7crhOJEDHo\\ns245+zRf3wKBgAHJLRbIbwU32GJtwZSgd2+gvCEneMzpTC0vRy7fOgAXVOYf0zSL\\nARI39NYyshYv4OOzGMB35wJwoZX/z4tbFXZGchUCi0/1cSAm3WtvXGfHK7dGyuIw\\nwqQz46P7GR7WXALOoaOUZali0mv5uNRc5GLCXUYtCHXbSvbj2NZ/uPtHAoGAdnec\\ny8H9zypp9gDv8hme9kNfaoOH2cw+gAUQXOqXZwudCSCEbl90rgad5QdEcnJRXMWH\\nZyFv7KXW0nJB7CUg/Vj/a7rKp42JtwuAiEp7z1OgS0gqnnDmplCK5K1ZLyQaUJ40\\nm/j7JqiVPyKrKjecextCeZelULUWeNlYnhuABeMCgYAiSHmLx8qm67kcOsSRsTxr\\nU01s5jxlHFYz+no3ZxiS6fwvsuxppiFeqRYD/zUBOcFZ+tKPU/5hH2Icu43ZApZx\\n0CwN2biiMKRMft8Wg8Lx5ZjS7il6roYPKHFlySQtoSoZXaHQLTMsW+wB+vUg5+YQ\\nTBN30eKadMx9Ws8RgLKQ/A==\\n-----END PRIVATE KEY-----\\n\",\n client_email:\n \"firebase-adminsdk-2yp4f@dayschallenge-373510.iam.gserviceaccount.com\",\n client_id: \"104734701364860430708\",\n auth_uri: \"https://accounts.google.com/o/oauth2/auth\",\n token_uri: \"https://oauth2.googleapis.com/token\",\n auth_provider_x509_cert_url: \"https://www.googleapis.com/oauth2/v1/certs\",\n client_x509_cert_url:\n \"https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-2yp4f%40dayschallenge-373510.iam.gserviceaccount.com\",\n universe_domain: \"googleapis.com\",\n};\n"],"names":["cert_key","type","project_id","private_key_id","private_key","client_email","client_id","auth_uri","token_uri","auth_provider_x509_cert_url","client_x509_cert_url","universe_domain"],"mappings":"AAAA,OAAO,MAAMA,WAAW;IACtBC,MAAM;IACNC,YAAY;IACZC,gBAAgB;IAChBC,aACE;IACFC,cACE;IACFC,WAAW;IACXC,UAAU;IACVC,WAAW;IACXC,6BAA6B;IAC7BC,sBACE;IACFC,iBAAiB;AACnB,EAAE"}
@@ -0,0 +1,50 @@
1
+ export interface AndroidMessage {
2
+ message: {
3
+ token: string | string[];
4
+ notification: {
5
+ body: string;
6
+ title: string;
7
+ };
8
+ };
9
+ }
10
+ export interface NotificationPayload {
11
+ name: string;
12
+ userUuid: string;
13
+ reminderType?: string;
14
+ delayHours?: number;
15
+ }
16
+ export interface EmailReminderPayload {
17
+ email: string;
18
+ timeZone?: string;
19
+ }
20
+ export interface NotificationTranslationRequest {
21
+ language: string;
22
+ text: string;
23
+ type?: NotificationTypes;
24
+ originalNotificationUuid: string;
25
+ }
26
+ export type NotificationTypes = "challenge_reminder_no_streak" | "challenge_reminder_streak" | "workout_reminder_no_streak" | "workout_reminder" | "rest_reminder_no_streak" | "rest_reminder" | "challenge_alert" | "workout_alert" | "rest_alert" | "workout_exp_alert" | "challenge_exp_alert";
27
+ export interface CreateNotificationRequest {
28
+ text: string;
29
+ type: NotificationTypes;
30
+ }
31
+ export interface WorkoutReminder extends NotificationPayload {
32
+ programUuid: string;
33
+ }
34
+ export interface NotificationRequest {
35
+ title: string;
36
+ body: string;
37
+ redirectPath?: string;
38
+ }
39
+ export interface GroupNotificationRequest {
40
+ notification: NotificationRequest;
41
+ group: NotificationGroups;
42
+ }
43
+ export declare enum NotificationGroups {
44
+ ALL = "ALL",
45
+ PREMIUM = "PREMIUM",
46
+ FREE = "FREE",
47
+ ALL_SHRED = "ALL_SHRED",
48
+ PREMIUM_SHRED = "PREMIUM_SHRED",
49
+ FREE_SHRED = "FREE_SHRED"
50
+ }
@@ -0,0 +1,11 @@
1
+ export var NotificationGroups;
2
+ (function(NotificationGroups) {
3
+ NotificationGroups["ALL"] = "ALL";
4
+ NotificationGroups["PREMIUM"] = "PREMIUM";
5
+ NotificationGroups["FREE"] = "FREE";
6
+ NotificationGroups["ALL_SHRED"] = "ALL_SHRED";
7
+ NotificationGroups["PREMIUM_SHRED"] = "PREMIUM_SHRED";
8
+ NotificationGroups["FREE_SHRED"] = "FREE_SHRED";
9
+ })(NotificationGroups || (NotificationGroups = {}));
10
+
11
+ //# sourceMappingURL=NotificationInterfaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/lib/models/NotificationInterfaces.ts"],"sourcesContent":["export interface AndroidMessage {\n message: {\n token: string | string[];\n notification: { body: string; title: string };\n };\n}\n\nexport interface NotificationPayload {\n name: string;\n userUuid: string;\n reminderType?: string;\n delayHours?: number;\n}\n\nexport interface EmailReminderPayload {\n email: string,\n timeZone?: string\n}\n\nexport interface NotificationTranslationRequest {\n language: string;\n text: string;\n type?: NotificationTypes;\n originalNotificationUuid: string;\n}\n\nexport type NotificationTypes =\n | \"challenge_reminder_no_streak\"\n | \"challenge_reminder_streak\"\n | \"workout_reminder_no_streak\"\n | \"workout_reminder\"\n | \"rest_reminder_no_streak\"\n | \"rest_reminder\"\n | \"challenge_alert\"\n | \"workout_alert\"\n | \"rest_alert\"\n | \"workout_exp_alert\"\n | \"challenge_exp_alert\";\n\nexport interface CreateNotificationRequest {\n text: string;\n type: NotificationTypes;\n}\n\nexport interface WorkoutReminder extends NotificationPayload {\n programUuid: string;\n}\nexport interface NotificationRequest {\n title: string;\n body: string;\n redirectPath?: string;\n}\n\nexport interface GroupNotificationRequest {\n notification: NotificationRequest;\n group: NotificationGroups;\n}\n\nexport enum NotificationGroups {\n ALL = \"ALL\",\n PREMIUM = \"PREMIUM\",\n FREE = \"FREE\",\n ALL_SHRED = \"ALL_SHRED\",\n PREMIUM_SHRED = \"PREMIUM_SHRED\",\n FREE_SHRED = \"FREE_SHRED\",\n}\n"],"names":["NotificationGroups","ALL","PREMIUM","FREE","ALL_SHRED","PREMIUM_SHRED","FREE_SHRED"],"mappings":"WA0DO;UAAKA,kBAAkB;IAAlBA,mBACVC,SAAAA;IADUD,mBAEVE,aAAAA;IAFUF,mBAGVG,UAAAA;IAHUH,mBAIVI,eAAAA;IAJUJ,mBAKVK,mBAAAA;IALUL,mBAMVM,gBAAAA;GANUN,uBAAAA"}
@@ -0,0 +1,14 @@
1
+ import apn from "apn";
2
+ import type { AndroidMessage, NotificationRequest } from "../models/NotificationInterfaces";
3
+ export default class NotificationsUtil {
4
+ private static apnProvider;
5
+ private static getAccessToken;
6
+ private static getAPNProvider;
7
+ static sendAppleNotification(notification: apn.Notification, token: string | string[]): Promise<void>;
8
+ static sendAndroidNotification(notification: AndroidMessage): Promise<void>;
9
+ private static buildAppleNotification;
10
+ private static buildAndroidNotification;
11
+ static sendNotification(userUuid: string, notification: NotificationRequest): Promise<void>;
12
+ static calculateDelayUntil10AM(timeZone: string, additionalDelay?: number): number;
13
+ static calculateDelayUntil6PM(timeZone: string): number;
14
+ }
@@ -0,0 +1,147 @@
1
+ import apn from "apn";
2
+ import axios, { isAxiosError } from "axios";
3
+ import * as dotenv from "dotenv";
4
+ import { google } from "googleapis";
5
+ import { cert_key } from "../enums/cert";
6
+ import { DeviceTokens } from "../dbmodels/DeviceTokens";
7
+ dotenv.config();
8
+ export default class NotificationsUtil {
9
+ static apnProvider = this.getAPNProvider();
10
+ static async getAccessToken() {
11
+ const key = cert_key;
12
+ const jwtClient = new google.auth.JWT({
13
+ email: key.client_email,
14
+ key: key.private_key,
15
+ scopes: [
16
+ "https://www.googleapis.com/auth/firebase.messaging"
17
+ ]
18
+ });
19
+ return new Promise((resolve, reject)=>{
20
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
21
+ jwtClient.authorize((err, tokens)=>{
22
+ if (err) {
23
+ reject(err);
24
+ return;
25
+ }
26
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
27
+ resolve(tokens.access_token);
28
+ });
29
+ });
30
+ }
31
+ static getAPNProvider() {
32
+ return new apn.Provider({
33
+ token: {
34
+ key: process.env.APN_KEY_PATH,
35
+ keyId: process.env.NOTIFICATIONS_KEY_ID,
36
+ teamId: process.env.NOTIFICATIONS_TEAM_ID
37
+ },
38
+ production: true
39
+ });
40
+ }
41
+ static async sendAppleNotification(notification, token) {
42
+ try {
43
+ await this.apnProvider.send(notification, token);
44
+ } catch (e) {
45
+ console.error(`ERROR: Could not send apple notification: ${e.message}`);
46
+ }
47
+ }
48
+ static async sendAndroidNotification(notification) {
49
+ try {
50
+ await axios.post("https://fcm.googleapis.com/v1/projects/dayschallenge-373510/messages:send", notification, {
51
+ headers: {
52
+ "Content-Type": "application/json",
53
+ Authorization: `Bearer ${await this.getAccessToken()}`
54
+ }
55
+ });
56
+ } catch (e) {
57
+ if (isAxiosError(e)) {
58
+ console.error(`ERROR: Could not send android notification: ${e.message}`);
59
+ }
60
+ }
61
+ }
62
+ static buildAppleNotification(notificationReq) {
63
+ const notification = new apn.Notification();
64
+ notification.topic = process.env.APPLE_BUNDLE_ID;
65
+ notification.priority = 10;
66
+ notification.expiry = Math.floor(Date.now() / 1000) + 3600;
67
+ notification.rawPayload = {
68
+ aps: {
69
+ alert: {
70
+ title: notificationReq.title,
71
+ body: notificationReq.body
72
+ },
73
+ "content-available": 1,
74
+ sound: "default",
75
+ redirectPath: notificationReq.redirectPath
76
+ }
77
+ };
78
+ return notification;
79
+ }
80
+ static buildAndroidNotification(notificationReq, token) {
81
+ if (Array.isArray(token)) {
82
+ return {
83
+ message: {
84
+ token: token,
85
+ notification: {
86
+ title: notificationReq.title,
87
+ body: notificationReq.body
88
+ }
89
+ }
90
+ };
91
+ }
92
+ return {
93
+ message: {
94
+ token: token,
95
+ notification: {
96
+ title: notificationReq.title,
97
+ body: notificationReq.body
98
+ }
99
+ }
100
+ };
101
+ }
102
+ static async sendNotification(userUuid, notification) {
103
+ const deviceToken = await DeviceTokens.findOne({
104
+ where: {
105
+ userUuid: userUuid
106
+ },
107
+ raw: true
108
+ });
109
+ if (!deviceToken) {
110
+ console.error(`ERROR: No token found for user ${userUuid}}`);
111
+ return;
112
+ }
113
+ deviceToken.platform === "ios" ? await this.sendAppleNotification(this.buildAppleNotification(notification), deviceToken.deviceToken) : await this.sendAndroidNotification(this.buildAndroidNotification(notification, deviceToken.deviceToken));
114
+ }
115
+ static calculateDelayUntil10AM(timeZone, additionalDelay = 0) {
116
+ const now = new Date(new Date().toLocaleString("en-US", {
117
+ timeZone
118
+ }));
119
+ // Create a Date object for 10 AM today in the user's time zone
120
+ const next10AM = new Date(now);
121
+ next10AM.setHours(10, 0, 0, 0);
122
+ // If the current time is past 10 AM, set the next 10 AM to tomorrow
123
+ if (now.getTime() > next10AM.getTime()) {
124
+ next10AM.setDate(next10AM.getDate() + 1);
125
+ }
126
+ next10AM.setDate(next10AM.getDate() + additionalDelay);
127
+ // Calculate the delay in milliseconds
128
+ return next10AM.getTime() - now.getTime();
129
+ }
130
+ static calculateDelayUntil6PM(timeZone) {
131
+ // Get the current date and time in the user's time zone
132
+ const now = new Date(new Date().toLocaleString("en-US", {
133
+ timeZone
134
+ }));
135
+ // Create a Date object for 6 PM today in the user's time zone
136
+ const next6PM = new Date(now);
137
+ next6PM.setHours(18, 0, 0, 0);
138
+ // If the current time is past 6 PM, set the next 6 PM to tomorrow
139
+ if (now.getTime() > next6PM.getTime()) {
140
+ next6PM.setDate(next6PM.getDate() + 1);
141
+ }
142
+ // Calculate the delay in milliseconds
143
+ return next6PM.getTime() - now.getTime();
144
+ }
145
+ }
146
+
147
+ //# sourceMappingURL=NotificationsUtil.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/lib/utils/NotificationsUtil.ts"],"sourcesContent":["import apn, { Provider } from \"apn\";\nimport axios, { isAxiosError } from \"axios\";\nimport * as dotenv from \"dotenv\";\nimport { google } from \"googleapis\";\nimport type { JWT } from \"google-auth-library\";\nimport { cert_key } from \"../enums/cert\";\nimport type {\n AndroidMessage,\n NotificationRequest\n} from \"../models/NotificationInterfaces\";\nimport {DeviceTokens} from \"../dbmodels/DeviceTokens\";\ndotenv.config();\n\nexport default class NotificationsUtil {\n private static apnProvider: Provider = this.getAPNProvider();\n\n private static async getAccessToken(): Promise<string> {\n const key = cert_key;\n\n const jwtClient: JWT = new google.auth.JWT({\n email: key.client_email,\n key: key.private_key,\n scopes: [\"https://www.googleapis.com/auth/firebase.messaging\"],\n });\n\n return new Promise<string>((resolve, reject) => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access\n jwtClient.authorize((err: any, tokens: any) => {\n if (err) {\n reject(err);\n return;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n resolve(tokens.access_token as string);\n });\n });\n }\n\n private static getAPNProvider(): Provider {\n return new apn.Provider({\n token: {\n key: process.env.APN_KEY_PATH as string,\n keyId: process.env.NOTIFICATIONS_KEY_ID as string,\n teamId: process.env.NOTIFICATIONS_TEAM_ID as string,\n },\n production: true,\n });\n }\n\n public static async sendAppleNotification(\n notification: apn.Notification,\n token: string | string[]\n ) {\n try {\n await this.apnProvider.send(notification, token);\n } catch (e) {\n console.error(\n `ERROR: Could not send apple notification: ${(e as Error).message}`\n );\n }\n }\n\n public static async sendAndroidNotification(notification: AndroidMessage) {\n try {\n await axios.post(\n \"https://fcm.googleapis.com/v1/projects/dayschallenge-373510/messages:send\",\n notification,\n {\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${await this.getAccessToken()}`,\n },\n }\n );\n } catch (e) {\n if (isAxiosError(e)) {\n console.error(\n `ERROR: Could not send android notification: ${(e as Error).message}`\n );\n }\n }\n }\n\n private static buildAppleNotification(notificationReq: NotificationRequest) {\n const notification: apn.Notification = new apn.Notification();\n notification.topic = process.env.APPLE_BUNDLE_ID as string;\n notification.priority = 10;\n notification.expiry = Math.floor(Date.now() / 1000) + 3600;\n notification.rawPayload = {\n aps: {\n alert: {\n title: notificationReq.title,\n body: notificationReq.body,\n },\n \"content-available\": 1,\n sound: \"default\",\n redirectPath: notificationReq.redirectPath,\n },\n };\n return notification;\n }\n\n private static buildAndroidNotification(\n notificationReq: NotificationRequest,\n token: string | string[]\n ): AndroidMessage {\n if (Array.isArray(token)) {\n return {\n message: {\n token: token,\n notification: {\n title: notificationReq.title,\n body: notificationReq.body,\n },\n },\n };\n }\n\n return {\n message: {\n token: token,\n notification: {\n title: notificationReq.title,\n body: notificationReq.body,\n },\n },\n };\n }\n\n\n public static async sendNotification(\n userUuid: string,\n notification: NotificationRequest\n ) {\n const deviceToken: DeviceTokens | null = await DeviceTokens.findOne({\n where: { userUuid: userUuid },\n raw: true,\n });\n\n if (!deviceToken) {\n console.error(`ERROR: No token found for user ${userUuid}}`);\n return;\n }\n\n deviceToken.platform === \"ios\"\n ? await this.sendAppleNotification(\n this.buildAppleNotification(notification),\n deviceToken.deviceToken\n )\n : await this.sendAndroidNotification(\n this.buildAndroidNotification(notification, deviceToken.deviceToken)\n );\n }\n\n public static calculateDelayUntil10AM(timeZone: string, additionalDelay = 0) {\n const now = new Date(new Date().toLocaleString(\"en-US\", { timeZone }));\n\n // Create a Date object for 10 AM today in the user's time zone\n const next10AM = new Date(now);\n next10AM.setHours(10, 0, 0, 0);\n\n // If the current time is past 10 AM, set the next 10 AM to tomorrow\n if (now.getTime() > next10AM.getTime()) {\n next10AM.setDate(next10AM.getDate() + 1);\n }\n next10AM.setDate(next10AM.getDate() + additionalDelay);\n // Calculate the delay in milliseconds\n return next10AM.getTime() - now.getTime();\n }\n\n public static calculateDelayUntil6PM(timeZone: string) {\n // Get the current date and time in the user's time zone\n const now = new Date(new Date().toLocaleString(\"en-US\", { timeZone }));\n\n // Create a Date object for 6 PM today in the user's time zone\n const next6PM = new Date(now);\n next6PM.setHours(18, 0, 0, 0);\n\n // If the current time is past 6 PM, set the next 6 PM to tomorrow\n if (now.getTime() > next6PM.getTime()) {\n next6PM.setDate(next6PM.getDate() + 1);\n }\n\n // Calculate the delay in milliseconds\n return next6PM.getTime() - now.getTime();\n }\n}\n"],"names":["apn","axios","isAxiosError","dotenv","google","cert_key","DeviceTokens","config","NotificationsUtil","apnProvider","getAPNProvider","getAccessToken","key","jwtClient","auth","JWT","email","client_email","private_key","scopes","Promise","resolve","reject","authorize","err","tokens","access_token","Provider","token","process","env","APN_KEY_PATH","keyId","NOTIFICATIONS_KEY_ID","teamId","NOTIFICATIONS_TEAM_ID","production","sendAppleNotification","notification","send","e","console","error","message","sendAndroidNotification","post","headers","Authorization","buildAppleNotification","notificationReq","Notification","topic","APPLE_BUNDLE_ID","priority","expiry","Math","floor","Date","now","rawPayload","aps","alert","title","body","sound","redirectPath","buildAndroidNotification","Array","isArray","sendNotification","userUuid","deviceToken","findOne","where","raw","platform","calculateDelayUntil10AM","timeZone","additionalDelay","toLocaleString","next10AM","setHours","getTime","setDate","getDate","calculateDelayUntil6PM","next6PM"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "90dc-core",
3
- "version": "1.6.0",
3
+ "version": "1.6.2",
4
4
  "description": "A package that contains utils and interfaces used to create 90dc",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -22,12 +22,15 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "@typescript-eslint/parser": "^5.53.0",
25
+ "apn": "^2.2.0",
25
26
  "axios": "^1.6.2",
26
27
  "debug": "^4.3.4",
27
28
  "dotenv": "^16.4.5",
28
29
  "eslint": "^8.34.0",
30
+ "google-auth-library": "^9.14.1",
29
31
  "googleapis": "^140.0.0",
30
32
  "jsonwebtoken": "^9.0.2",
33
+ "sequelize": "^6.37.4",
31
34
  "sequelize-typescript": "^2.1.5",
32
35
  "winston": "^3.8.2"
33
36
  },
@@ -0,0 +1,24 @@
1
+ import { Column, DataType, Model, Table } from "sequelize-typescript";
2
+
3
+ @Table
4
+ export class DeviceTokens extends Model {
5
+ @Column({
6
+ type: DataType.UUID,
7
+ defaultValue: DataType.UUID,
8
+ allowNull: false,
9
+ primaryKey: true,
10
+ })
11
+ declare userUuid: string;
12
+
13
+ @Column({
14
+ type: DataType.TEXT,
15
+ allowNull: false,
16
+ })
17
+ declare deviceToken: string;
18
+
19
+ @Column({
20
+ type: DataType.TEXT,
21
+ allowNull: true,
22
+ })
23
+ declare platform: "ios" | "android";
24
+ }
@@ -0,0 +1,39 @@
1
+ import { Column, DataType, HasMany, Model, Table } from "sequelize-typescript";
2
+ import {TranslatedNotification} from "./TranslatedNotification";
3
+
4
+ @Table
5
+ export class NotificationModels extends Model {
6
+ @Column({
7
+ type: DataType.UUID,
8
+ defaultValue: DataType.UUID,
9
+ allowNull: false,
10
+ primaryKey: true,
11
+ })
12
+ declare uuid: string;
13
+
14
+ @Column({
15
+ type: DataType.TEXT,
16
+ allowNull: false,
17
+ })
18
+ declare type:
19
+ | "challenge_reminder_no_streak"
20
+ | "challenge_reminder_streak"
21
+ | "workout_reminder_no_streak"
22
+ | "workout_reminder"
23
+ | "rest_reminder_no_streak"
24
+ | "rest_reminder"
25
+ | "challenge_alert"
26
+ | "workout_alert"
27
+ | "rest_alert"
28
+ | "workout_exp_alert"
29
+ | "challenge_exp_alert";
30
+
31
+ @Column({
32
+ type: DataType.TEXT,
33
+ allowNull: false,
34
+ })
35
+ declare text: string;
36
+
37
+ @HasMany(() => TranslatedNotification)
38
+ declare translations: TranslatedNotification[];
39
+ }
@@ -0,0 +1,42 @@
1
+ import {
2
+ BelongsTo,
3
+ Column,
4
+ DataType,
5
+ ForeignKey,
6
+ Model,
7
+ Table,
8
+ } from "sequelize-typescript";
9
+ import { NotificationModels } from "./NotificationModels";
10
+
11
+ @Table
12
+ export class TranslatedNotification extends Model {
13
+ @Column({
14
+ type: DataType.UUID,
15
+ defaultValue: DataType.UUID,
16
+ allowNull: false,
17
+ primaryKey: true,
18
+ })
19
+ declare uuid: string;
20
+
21
+ @ForeignKey(() => NotificationModels)
22
+ @Column({
23
+ type: DataType.UUID,
24
+ allowNull: false,
25
+ })
26
+ declare notificationUuid: string;
27
+
28
+ @Column({
29
+ type: DataType.STRING,
30
+ allowNull: false,
31
+ })
32
+ declare language: string;
33
+
34
+ @Column({
35
+ type: DataType.TEXT,
36
+ allowNull: false,
37
+ })
38
+ declare text: string;
39
+
40
+ @BelongsTo(() => NotificationModels)
41
+ declare notification: NotificationModels;
42
+ }
@@ -0,0 +1,46 @@
1
+ import {
2
+ BelongsTo,
3
+ Column,
4
+ DataType,
5
+ Default,
6
+ ForeignKey,
7
+ Index,
8
+ Model,
9
+ PrimaryKey,
10
+ Table,
11
+ } from "sequelize-typescript";
12
+ import { Program } from "./Program";
13
+
14
+ @Table({ timestamps: true })
15
+ export class ThirtyDayChallenge extends Model {
16
+ @PrimaryKey
17
+ @Default(DataType.UUIDV4)
18
+ @Column(DataType.UUID)
19
+ declare uuid: string;
20
+
21
+ @Index
22
+ @ForeignKey(() => Program)
23
+ @Column(DataType.UUID)
24
+ declare programUuid: string;
25
+
26
+ @Column({ type: DataType.STRING, allowNull: false })
27
+ declare challengeType: string;
28
+
29
+ @Column({ type: DataType.INTEGER, allowNull: false, defaultValue: 100 })
30
+ declare goal: number;
31
+
32
+ @Column({ type: DataType.INTEGER, allowNull: false })
33
+ declare order: number;
34
+
35
+ @Column({ type: DataType.INTEGER, allowNull: false, defaultValue: 0 })
36
+ declare currentReps: number;
37
+
38
+ @Column({ type: DataType.BOOLEAN, allowNull: false, defaultValue: false })
39
+ declare isFinished: boolean;
40
+
41
+ @Column({ type: DataType.BOOLEAN, allowNull: false, defaultValue: false })
42
+ declare isLocked: boolean;
43
+
44
+ @BelongsTo(() => Program)
45
+ declare program: Program;
46
+ }
@@ -0,0 +1,39 @@
1
+ import {
2
+ BelongsTo,
3
+ Column,
4
+ DataType,
5
+ Default,
6
+ ForeignKey,
7
+ Index,
8
+ Model,
9
+ PrimaryKey,
10
+ Table,
11
+ } from "sequelize-typescript";
12
+ import { Program } from "./Program";
13
+
14
+ @Table({ timestamps: true })
15
+ export class ThirtyDayChallengeStrengthTest extends Model {
16
+ @PrimaryKey
17
+ @Default(DataType.UUIDV4)
18
+ @Column(DataType.UUID)
19
+ declare uuid: string;
20
+
21
+ @ForeignKey(() => Program)
22
+ @Column(DataType.UUID)
23
+ declare programUuid: string;
24
+
25
+ @Column({ type: DataType.STRING, allowNull: false })
26
+ declare challengeType: string;
27
+
28
+ @Column({ type: DataType.INTEGER, allowNull: false, defaultValue: 0 })
29
+ declare maxReps: number;
30
+
31
+ @Column({ type: DataType.INTEGER, allowNull: false })
32
+ declare order: number;
33
+
34
+ @Column({ type: DataType.BOOLEAN, allowNull: false, defaultValue: false })
35
+ declare isFinished: boolean;
36
+
37
+ @BelongsTo(() => Program)
38
+ declare program: Program;
39
+ }