90dc-core 1.19.4 → 1.19.6
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.
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/Errors/AppError.js +104 -0
- package/dist/lib/Errors/AppError.js.map +1 -0
- package/dist/lib/Errors/Errors.js +42 -0
- package/dist/lib/Errors/Errors.js.map +1 -0
- package/dist/lib/classes/Database.js +154 -0
- package/dist/lib/classes/Database.js.map +1 -0
- package/dist/lib/classes/Redis.js +63 -0
- package/dist/lib/classes/Redis.js.map +1 -0
- package/dist/lib/clients/EmailClient.js +188 -0
- package/dist/lib/clients/EmailClient.js.map +1 -0
- package/dist/lib/clients/FirebasePushNotificationClient.js +688 -0
- package/dist/lib/clients/FirebasePushNotificationClient.js.map +1 -0
- package/dist/lib/clients/ImagesClient.d.ts +2 -1
- package/dist/lib/clients/ImagesClient.d.ts.map +1 -1
- package/dist/lib/clients/ImagesClient.js +436 -0
- package/dist/lib/clients/ImagesClient.js.map +1 -0
- package/dist/lib/clients/MailingClient.js +84 -0
- package/dist/lib/clients/MailingClient.js.map +1 -0
- package/dist/lib/clients/PushNotificationClient.js +478 -0
- package/dist/lib/clients/PushNotificationClient.js.map +1 -0
- package/dist/lib/clients/types/email.types.js +3 -0
- package/dist/lib/clients/types/email.types.js.map +1 -0
- package/dist/lib/clients/types/images.types.js +3 -0
- package/dist/lib/clients/types/images.types.js.map +1 -0
- package/dist/lib/clients/types/mailing.types.js +3 -0
- package/dist/lib/clients/types/mailing.types.js.map +1 -0
- package/dist/lib/config/ConfigValidator.js +162 -0
- package/dist/lib/config/ConfigValidator.js.map +1 -0
- package/dist/lib/controllers/BaseController.js +64 -0
- package/dist/lib/controllers/BaseController.js.map +1 -0
- package/dist/lib/db/migrations/20260330000000-create-user-progress-photos.js +60 -0
- package/dist/lib/db/migrations/20260330000000-create-user-progress-photos.js.map +1 -0
- package/dist/lib/dbmodels/coaching/Answer.js +51 -0
- package/dist/lib/dbmodels/coaching/Answer.js.map +1 -0
- package/dist/lib/dbmodels/coaching/ClientNote.js +75 -0
- package/dist/lib/dbmodels/coaching/ClientNote.js.map +1 -0
- package/dist/lib/dbmodels/coaching/ClientTag.js +45 -0
- package/dist/lib/dbmodels/coaching/ClientTag.js.map +1 -0
- package/dist/lib/dbmodels/coaching/Question.js +60 -0
- package/dist/lib/dbmodels/coaching/Question.js.map +1 -0
- package/dist/lib/dbmodels/coaching/Questionnaire.js +39 -0
- package/dist/lib/dbmodels/coaching/Questionnaire.js.map +1 -0
- package/dist/lib/dbmodels/coaching/QuestionnaireResponse.js +42 -0
- package/dist/lib/dbmodels/coaching/QuestionnaireResponse.js.map +1 -0
- package/dist/lib/dbmodels/coaching/WeeklyCheckIn.js +69 -0
- package/dist/lib/dbmodels/coaching/WeeklyCheckIn.js.map +1 -0
- package/dist/lib/dbmodels/coaching/WeightRecord.js +49 -0
- package/dist/lib/dbmodels/coaching/WeightRecord.js.map +1 -0
- package/dist/lib/dbmodels/diet/DietDay.js +50 -0
- package/dist/lib/dbmodels/diet/DietDay.js.map +1 -0
- package/dist/lib/dbmodels/diet/DietMeal.js +74 -0
- package/dist/lib/dbmodels/diet/DietMeal.js.map +1 -0
- package/dist/lib/dbmodels/diet/DietMealCompletion.js +69 -0
- package/dist/lib/dbmodels/diet/DietMealCompletion.js.map +1 -0
- package/dist/lib/dbmodels/diet/DietMealRecipe.js +67 -0
- package/dist/lib/dbmodels/diet/DietMealRecipe.js.map +1 -0
- package/dist/lib/dbmodels/diet/DietMealRecipeIngredient.js +46 -0
- package/dist/lib/dbmodels/diet/DietMealRecipeIngredient.js.map +1 -0
- package/dist/lib/dbmodels/diet/DietProgram.js +98 -0
- package/dist/lib/dbmodels/diet/DietProgram.js.map +1 -0
- package/dist/lib/dbmodels/diet/Ingredient.js +88 -0
- package/dist/lib/dbmodels/diet/Ingredient.js.map +1 -0
- package/dist/lib/dbmodels/diet/IngredientTag.js +64 -0
- package/dist/lib/dbmodels/diet/IngredientTag.js.map +1 -0
- package/dist/lib/dbmodels/diet/IngredientTags.js +29 -0
- package/dist/lib/dbmodels/diet/IngredientTags.js.map +1 -0
- package/dist/lib/dbmodels/diet/Recipe.js +173 -0
- package/dist/lib/dbmodels/diet/Recipe.js.map +1 -0
- package/dist/lib/dbmodels/diet/RecipeIngredient.js +78 -0
- package/dist/lib/dbmodels/diet/RecipeIngredient.js.map +1 -0
- package/dist/lib/dbmodels/diet/RecipeTag.js +44 -0
- package/dist/lib/dbmodels/diet/RecipeTag.js.map +1 -0
- package/dist/lib/dbmodels/diet/RecipeTags.js +24 -0
- package/dist/lib/dbmodels/diet/RecipeTags.js.map +1 -0
- package/dist/lib/dbmodels/diet/ShoppingList.js +69 -0
- package/dist/lib/dbmodels/diet/ShoppingList.js.map +1 -0
- package/dist/lib/dbmodels/diet/ShoppingListItem.js +66 -0
- package/dist/lib/dbmodels/diet/ShoppingListItem.js.map +1 -0
- package/dist/lib/dbmodels/diet/TranslatedRecipe.js +122 -0
- package/dist/lib/dbmodels/diet/TranslatedRecipe.js.map +1 -0
- package/dist/lib/dbmodels/diet/TranslatedRecipeTag.js +47 -0
- package/dist/lib/dbmodels/diet/TranslatedRecipeTag.js.map +1 -0
- package/dist/lib/dbmodels/diet/TranslatedRecipeTags.js +24 -0
- package/dist/lib/dbmodels/diet/TranslatedRecipeTags.js.map +1 -0
- package/dist/lib/dbmodels/diet/UserDietPreferences.js +85 -0
- package/dist/lib/dbmodels/diet/UserDietPreferences.js.map +1 -0
- package/dist/lib/dbmodels/gamification/Badge.js +62 -0
- package/dist/lib/dbmodels/gamification/Badge.js.map +1 -0
- package/dist/lib/dbmodels/gamification/StreaksLog.js +37 -0
- package/dist/lib/dbmodels/gamification/StreaksLog.js.map +1 -0
- package/dist/lib/dbmodels/gamification/TranslatedBadge.js +45 -0
- package/dist/lib/dbmodels/gamification/TranslatedBadge.js.map +1 -0
- package/dist/lib/dbmodels/gamification/xpAndLeaderboards/UserRankHistory.js +48 -0
- package/dist/lib/dbmodels/gamification/xpAndLeaderboards/UserRankHistory.js.map +1 -0
- package/dist/lib/dbmodels/gamification/xpAndLeaderboards/XpEvent.js +53 -0
- package/dist/lib/dbmodels/gamification/xpAndLeaderboards/XpEvent.js.map +1 -0
- package/dist/lib/dbmodels/gamification/xpAndLeaderboards/XpTransaction.js +68 -0
- package/dist/lib/dbmodels/gamification/xpAndLeaderboards/XpTransaction.js.map +1 -0
- package/dist/lib/dbmodels/index.js +288 -0
- package/dist/lib/dbmodels/index.js.map +1 -0
- package/dist/lib/dbmodels/nonconsprogram/NonConsumableProgram.d.ts +32 -0
- package/dist/lib/dbmodels/nonconsprogram/NonConsumableProgram.d.ts.map +1 -0
- package/dist/lib/dbmodels/nonconsprogram/NonConsumableProgram.js +155 -0
- package/dist/lib/dbmodels/nonconsprogram/NonConsumableProgram.js.map +1 -0
- package/dist/lib/dbmodels/nonconsprogram/NonConsumableProgramWebContent.d.ts +22 -0
- package/dist/lib/dbmodels/nonconsprogram/NonConsumableProgramWebContent.d.ts.map +1 -0
- package/dist/lib/dbmodels/nonconsprogram/NonConsumableProgramWebContent.js +108 -0
- package/dist/lib/dbmodels/nonconsprogram/NonConsumableProgramWebContent.js.map +1 -0
- package/dist/lib/dbmodels/nonconsprogram/TranslatedConsumableProgram.d.ts +20 -0
- package/dist/lib/dbmodels/nonconsprogram/TranslatedConsumableProgram.d.ts.map +1 -0
- package/dist/lib/dbmodels/nonconsprogram/TranslatedConsumableProgram.js +97 -0
- package/dist/lib/dbmodels/nonconsprogram/TranslatedConsumableProgram.js.map +1 -0
- package/dist/lib/dbmodels/nonconsprogram/TranslatedNonConsumableProgramWebContent.d.ts +22 -0
- package/dist/lib/dbmodels/nonconsprogram/TranslatedNonConsumableProgramWebContent.d.ts.map +1 -0
- package/dist/lib/dbmodels/nonconsprogram/TranslatedNonConsumableProgramWebContent.js +115 -0
- package/dist/lib/dbmodels/nonconsprogram/TranslatedNonConsumableProgramWebContent.js.map +1 -0
- package/dist/lib/dbmodels/nonconsprogram/UserNonConsumableProgram.d.ts +7 -0
- package/dist/lib/dbmodels/nonconsprogram/UserNonConsumableProgram.d.ts.map +1 -0
- package/dist/lib/dbmodels/nonconsprogram/UserNonConsumableProgram.js +41 -0
- package/dist/lib/dbmodels/nonconsprogram/UserNonConsumableProgram.js.map +1 -0
- package/dist/lib/dbmodels/notifications/NotificationModels.js +38 -0
- package/dist/lib/dbmodels/notifications/NotificationModels.js.map +1 -0
- package/dist/lib/dbmodels/notifications/TranslatedNotification.js +45 -0
- package/dist/lib/dbmodels/notifications/TranslatedNotification.js.map +1 -0
- package/dist/lib/dbmodels/program/Challenge.d.ts +13 -0
- package/dist/lib/dbmodels/program/Challenge.d.ts.map +1 -0
- package/dist/lib/dbmodels/program/Challenge.js +63 -0
- package/dist/lib/dbmodels/program/Challenge.js.map +1 -0
- package/dist/lib/dbmodels/program/ChallengeBlueprint.js +75 -0
- package/dist/lib/dbmodels/program/ChallengeBlueprint.js.map +1 -0
- package/dist/lib/dbmodels/program/CircularProgramDraft.js +82 -0
- package/dist/lib/dbmodels/program/CircularProgramDraft.js.map +1 -0
- package/dist/lib/dbmodels/program/CoachExerciseNote.js +61 -0
- package/dist/lib/dbmodels/program/CoachExerciseNote.js.map +1 -0
- package/dist/lib/dbmodels/program/CustomProgramBlueprint.js +84 -0
- package/dist/lib/dbmodels/program/CustomProgramBlueprint.js.map +1 -0
- package/dist/lib/dbmodels/program/CustomStrengthTest.js +55 -0
- package/dist/lib/dbmodels/program/CustomStrengthTest.js.map +1 -0
- package/dist/lib/dbmodels/program/CustomStrengthTestExercises.js +69 -0
- package/dist/lib/dbmodels/program/CustomStrengthTestExercises.js.map +1 -0
- package/dist/lib/dbmodels/program/CustomWorkoutBlueprint.js +58 -0
- package/dist/lib/dbmodels/program/CustomWorkoutBlueprint.js.map +1 -0
- package/dist/lib/dbmodels/program/Exercise.d.ts +23 -0
- package/dist/lib/dbmodels/program/Exercise.d.ts.map +1 -0
- package/dist/lib/dbmodels/program/Exercise.js +101 -0
- package/dist/lib/dbmodels/program/Exercise.js.map +1 -0
- package/dist/lib/dbmodels/program/ExerciseModels.d.ts +28 -0
- package/dist/lib/dbmodels/program/ExerciseModels.d.ts.map +1 -0
- package/dist/lib/dbmodels/program/ExerciseModels.js +149 -0
- package/dist/lib/dbmodels/program/ExerciseModels.js.map +1 -0
- package/dist/lib/dbmodels/program/Program.d.ts +15 -0
- package/dist/lib/dbmodels/program/Program.d.ts.map +1 -0
- package/dist/lib/dbmodels/program/Program.js +76 -0
- package/dist/lib/dbmodels/program/Program.js.map +1 -0
- package/dist/lib/dbmodels/program/ProgressEntry.d.ts +26 -0
- package/dist/lib/dbmodels/program/ProgressEntry.d.ts.map +1 -0
- package/dist/lib/dbmodels/program/ProgressEntry.js +77 -0
- package/dist/lib/dbmodels/program/ProgressEntry.js.map +1 -0
- package/dist/lib/dbmodels/program/RestDay.js +33 -0
- package/dist/lib/dbmodels/program/RestDay.js.map +1 -0
- package/dist/lib/dbmodels/program/StrengthTest.d.ts +10 -0
- package/dist/lib/dbmodels/program/StrengthTest.d.ts.map +1 -0
- package/dist/lib/dbmodels/program/StrengthTest.js +39 -0
- package/dist/lib/dbmodels/program/StrengthTest.js.map +1 -0
- package/dist/lib/dbmodels/program/StrengthTestExercise.d.ts +15 -0
- package/dist/lib/dbmodels/program/StrengthTestExercise.d.ts.map +1 -0
- package/dist/lib/dbmodels/program/StrengthTestExercise.js +72 -0
- package/dist/lib/dbmodels/program/StrengthTestExercise.js.map +1 -0
- package/dist/lib/dbmodels/program/StrengthTestSession.js +73 -0
- package/dist/lib/dbmodels/program/StrengthTestSession.js.map +1 -0
- package/dist/lib/dbmodels/program/Superset.d.ts +13 -0
- package/dist/lib/dbmodels/program/Superset.d.ts.map +1 -0
- package/dist/lib/dbmodels/program/Superset.js +46 -0
- package/dist/lib/dbmodels/program/Superset.js.map +1 -0
- package/dist/lib/dbmodels/program/ThirtyDayChallenge.js +70 -0
- package/dist/lib/dbmodels/program/ThirtyDayChallenge.js.map +1 -0
- package/dist/lib/dbmodels/program/ThirtyDayChallengeStrengthTest.js +55 -0
- package/dist/lib/dbmodels/program/ThirtyDayChallengeStrengthTest.js.map +1 -0
- package/dist/lib/dbmodels/program/TranslatedChallenge.d.ts +15 -0
- package/dist/lib/dbmodels/program/TranslatedChallenge.d.ts.map +1 -0
- package/dist/lib/dbmodels/program/TranslatedChallenge.js +69 -0
- package/dist/lib/dbmodels/program/TranslatedChallenge.js.map +1 -0
- package/dist/lib/dbmodels/program/TranslatedExerciseModel.d.ts +25 -0
- package/dist/lib/dbmodels/program/TranslatedExerciseModel.d.ts.map +1 -0
- package/dist/lib/dbmodels/program/TranslatedExerciseModel.js +123 -0
- package/dist/lib/dbmodels/program/TranslatedExerciseModel.js.map +1 -0
- package/dist/lib/dbmodels/program/TranslatedStrengthTest.d.ts +12 -0
- package/dist/lib/dbmodels/program/TranslatedStrengthTest.d.ts.map +1 -0
- package/dist/lib/dbmodels/program/TranslatedStrengthTest.js +45 -0
- package/dist/lib/dbmodels/program/TranslatedStrengthTest.js.map +1 -0
- package/dist/lib/dbmodels/program/TranslatedStrengthTestExercise.d.ts +16 -0
- package/dist/lib/dbmodels/program/TranslatedStrengthTestExercise.d.ts.map +1 -0
- package/dist/lib/dbmodels/program/TranslatedStrengthTestExercise.js +78 -0
- package/dist/lib/dbmodels/program/TranslatedStrengthTestExercise.js.map +1 -0
- package/dist/lib/dbmodels/program/UserChallenge.d.ts +10 -0
- package/dist/lib/dbmodels/program/UserChallenge.d.ts.map +1 -0
- package/dist/lib/dbmodels/program/UserChallenge.js +47 -0
- package/dist/lib/dbmodels/program/UserChallenge.js.map +1 -0
- package/dist/lib/dbmodels/program/UserExerciseNote.js +61 -0
- package/dist/lib/dbmodels/program/UserExerciseNote.js.map +1 -0
- package/dist/lib/dbmodels/program/UserStrengthTests.d.ts +11 -0
- package/dist/lib/dbmodels/program/UserStrengthTests.d.ts.map +1 -0
- package/dist/lib/dbmodels/program/UserStrengthTests.js +54 -0
- package/dist/lib/dbmodels/program/UserStrengthTests.js.map +1 -0
- package/dist/lib/dbmodels/program/Workout.d.ts +14 -0
- package/dist/lib/dbmodels/program/Workout.d.ts.map +1 -0
- package/dist/lib/dbmodels/program/Workout.js +66 -0
- package/dist/lib/dbmodels/program/Workout.js.map +1 -0
- package/dist/lib/dbmodels/program/WorkoutCompletion.js +65 -0
- package/dist/lib/dbmodels/program/WorkoutCompletion.js.map +1 -0
- package/dist/lib/dbmodels/program/WorkoutSession.js +93 -0
- package/dist/lib/dbmodels/program/WorkoutSession.js.map +1 -0
- package/dist/lib/dbmodels/subscription/Subscription.d.ts +19 -0
- package/dist/lib/dbmodels/subscription/Subscription.d.ts.map +1 -0
- package/dist/lib/dbmodels/subscription/Subscription.js +91 -0
- package/dist/lib/dbmodels/subscription/Subscription.js.map +1 -0
- package/dist/lib/dbmodels/subscription/SubscriptionEvent.js +79 -0
- package/dist/lib/dbmodels/subscription/SubscriptionEvent.js.map +1 -0
- package/dist/lib/dbmodels/subscription/SubscriptionLog.d.ts +9 -0
- package/dist/lib/dbmodels/subscription/SubscriptionLog.d.ts.map +1 -0
- package/dist/lib/dbmodels/subscription/SubscriptionLog.js +42 -0
- package/dist/lib/dbmodels/subscription/SubscriptionLog.js.map +1 -0
- package/dist/lib/dbmodels/subscription/SubscriptionRefund.js +92 -0
- package/dist/lib/dbmodels/subscription/SubscriptionRefund.js.map +1 -0
- package/dist/lib/dbmodels/user/DeviceTokens.js +34 -0
- package/dist/lib/dbmodels/user/DeviceTokens.js.map +1 -0
- package/dist/lib/dbmodels/user/PersistedUser.d.ts +43 -0
- package/dist/lib/dbmodels/user/PersistedUser.d.ts.map +1 -0
- package/dist/lib/dbmodels/user/PersistedUser.js +237 -0
- package/dist/lib/dbmodels/user/PersistedUser.js.map +1 -0
- package/dist/lib/dbmodels/user/UserAddons.js +26 -0
- package/dist/lib/dbmodels/user/UserAddons.js.map +1 -0
- package/dist/lib/dbmodels/user/UserBadges.js +63 -0
- package/dist/lib/dbmodels/user/UserBadges.js.map +1 -0
- package/dist/lib/dbmodels/user/UserCoach.js +40 -0
- package/dist/lib/dbmodels/user/UserCoach.js.map +1 -0
- package/dist/lib/dbmodels/user/UserDiscount.js +24 -0
- package/dist/lib/dbmodels/user/UserDiscount.js.map +1 -0
- package/dist/lib/dbmodels/user/UserOptions.js +34 -0
- package/dist/lib/dbmodels/user/UserOptions.js.map +1 -0
- package/dist/lib/dbmodels/user/UserProgressPhoto.js +59 -0
- package/dist/lib/dbmodels/user/UserProgressPhoto.js.map +1 -0
- package/dist/lib/dbmodels/user/UserStreaks.js +64 -0
- package/dist/lib/dbmodels/user/UserStreaks.js.map +1 -0
- package/dist/lib/dbmodels/user/UsersFriends.js +46 -0
- package/dist/lib/dbmodels/user/UsersFriends.js.map +1 -0
- package/dist/lib/enums/ProgramEnums.d.ts +18 -0
- package/dist/lib/enums/ProgramEnums.d.ts.map +1 -0
- package/dist/lib/enums/ProgramEnums.js +22 -0
- package/dist/lib/enums/ProgramEnums.js.map +1 -0
- package/dist/lib/enums/ProgramTemplates.js +738 -0
- package/dist/lib/enums/ProgramTemplates.js.map +1 -0
- package/dist/lib/middlewares/ErrorMiddleware.js +141 -0
- package/dist/lib/middlewares/ErrorMiddleware.js.map +1 -0
- package/dist/lib/middlewares/ValidationMiddleware.js +24 -0
- package/dist/lib/middlewares/ValidationMiddleware.js.map +1 -0
- package/dist/lib/models/BlueprintInterfaces.js +3 -0
- package/dist/lib/models/BlueprintInterfaces.js.map +1 -0
- package/dist/lib/models/ExerciseInterfaces.d.ts +68 -0
- package/dist/lib/models/ExerciseInterfaces.d.ts.map +1 -0
- package/dist/lib/models/ExerciseInterfaces.js +3 -0
- package/dist/lib/models/ExerciseInterfaces.js.map +1 -0
- package/dist/lib/models/NotificationInterfaces.js +11 -0
- package/dist/lib/models/NotificationInterfaces.js.map +1 -0
- package/dist/lib/models/ProgramInterfaces.js +3 -0
- package/dist/lib/models/ProgramInterfaces.js.map +1 -0
- package/dist/lib/models/UserInterfaces.js +3 -0
- package/dist/lib/models/UserInterfaces.js.map +1 -0
- package/dist/lib/models/WorkoutInterfaces.js +3 -0
- package/dist/lib/models/WorkoutInterfaces.js.map +1 -0
- package/dist/lib/scripts/cli.js +82 -0
- package/dist/lib/scripts/cli.js.map +1 -0
- package/dist/lib/scripts/populate-exercise-thumbnails.js +64 -0
- package/dist/lib/scripts/populate-exercise-thumbnails.js.map +1 -0
- package/dist/lib/scripts/setup-database.js +43 -0
- package/dist/lib/scripts/setup-database.js.map +1 -0
- package/dist/lib/scripts/verify-indexes.js +94 -0
- package/dist/lib/scripts/verify-indexes.js.map +1 -0
- package/dist/lib/testing/testFixtures.js +520 -0
- package/dist/lib/testing/testFixtures.js.map +1 -0
- package/dist/lib/testing/testHelpers.js +149 -0
- package/dist/lib/testing/testHelpers.js.map +1 -0
- package/dist/lib/utils/AuthenticationUtil.js +481 -0
- package/dist/lib/utils/AuthenticationUtil.js.map +1 -0
- package/dist/lib/utils/Logger.js +242 -0
- package/dist/lib/utils/Logger.js.map +1 -0
- package/dist/lib/utils/NotificationClient.js +371 -0
- package/dist/lib/utils/NotificationClient.js.map +1 -0
- package/dist/lib/utils/NotificationsUtil.js +95 -0
- package/dist/lib/utils/NotificationsUtil.js.map +1 -0
- package/dist/lib/utils/SecretManager.js +107 -0
- package/dist/lib/utils/SecretManager.js.map +1 -0
- package/dist/lib/utils/SentryUtil.js +140 -0
- package/dist/lib/utils/SentryUtil.js.map +1 -0
- package/dist/lib/utils/imageValidation.js +31 -0
- package/dist/lib/utils/imageValidation.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { isAxiosError } from "axios";
|
|
2
|
+
import { createLogger, format, transports } from "winston";
|
|
3
|
+
import { isSentryEnabled, reportMessageToSentry } from "./SentryUtil.js";
|
|
4
|
+
function safeStringify(value) {
|
|
5
|
+
const seen = new WeakSet();
|
|
6
|
+
return JSON.stringify(value, (key, val)=>{
|
|
7
|
+
// drop known circular/noisy fields from axios
|
|
8
|
+
if (key === 'request' || key === 'socket' || key === '_httpMessage') return undefined;
|
|
9
|
+
if (key === 'config' && val && typeof val === 'object') {
|
|
10
|
+
// pick only safe axios config fields
|
|
11
|
+
const { url, method, headers, params, data, timeout } = val;
|
|
12
|
+
return {
|
|
13
|
+
url,
|
|
14
|
+
method,
|
|
15
|
+
headers,
|
|
16
|
+
params,
|
|
17
|
+
data,
|
|
18
|
+
timeout
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
if (key === 'response' && val && typeof val === 'object') {
|
|
22
|
+
const { status, statusText, headers, data } = val;
|
|
23
|
+
return {
|
|
24
|
+
status,
|
|
25
|
+
statusText,
|
|
26
|
+
headers,
|
|
27
|
+
data
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
if (typeof val === 'object' && val !== null) {
|
|
31
|
+
if (seen.has(val)) return '[Circular]';
|
|
32
|
+
seen.add(val);
|
|
33
|
+
}
|
|
34
|
+
return val;
|
|
35
|
+
}, 2);
|
|
36
|
+
}
|
|
37
|
+
export class Log {
|
|
38
|
+
static instance = null;
|
|
39
|
+
logger;
|
|
40
|
+
baseName;
|
|
41
|
+
constructor(baseName){
|
|
42
|
+
this.baseName = baseName;
|
|
43
|
+
const isProduction = process.env.ENVIRONMENT === "production";
|
|
44
|
+
const logFormat = format.printf(({ level, message, timestamp, stack, ...meta })=>{
|
|
45
|
+
const namespace = isProduction ? this.baseName : level === "error" ? `\x1b[31m${this.baseName}\x1b[39m` : `\x1b[35m${this.baseName}\x1b[39m`;
|
|
46
|
+
const { namespace: _, level: __, message: ___, timestamp: ____, stack: _____, ...rest } = meta;
|
|
47
|
+
let output = `${timestamp ? `[${timestamp}] ` : ""}${namespace} ${message}`;
|
|
48
|
+
delete rest.name;
|
|
49
|
+
delete rest.code;
|
|
50
|
+
delete rest.statusCode;
|
|
51
|
+
if (Object.keys(rest).length > 0) {
|
|
52
|
+
output += ` ${safeStringify(rest)}`;
|
|
53
|
+
}
|
|
54
|
+
if (stack) output += `\n${stack}`;
|
|
55
|
+
return output;
|
|
56
|
+
});
|
|
57
|
+
this.logger = createLogger({
|
|
58
|
+
level: "debug",
|
|
59
|
+
format: format.combine(format.timestamp({
|
|
60
|
+
format: "YYYY-MM-DD HH:mm:ss"
|
|
61
|
+
}), format.errors({
|
|
62
|
+
stack: true
|
|
63
|
+
}), logFormat),
|
|
64
|
+
transports: [
|
|
65
|
+
new transports.Console()
|
|
66
|
+
]
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
static getInstance() {
|
|
70
|
+
if (!Log.instance) {
|
|
71
|
+
const baseName = "@90DC:" + (process.env.npm_package_name || "package-name-not-specified");
|
|
72
|
+
Log.instance = new Log(baseName);
|
|
73
|
+
}
|
|
74
|
+
return Log.instance;
|
|
75
|
+
}
|
|
76
|
+
static extendInstance(name) {
|
|
77
|
+
return this.getInstance().extend(name);
|
|
78
|
+
}
|
|
79
|
+
debug(message, metadata) {
|
|
80
|
+
this.logger.debug(message, {
|
|
81
|
+
namespace: this.baseName,
|
|
82
|
+
...metadata
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
info(message, metadata) {
|
|
86
|
+
this.logger.info(message, {
|
|
87
|
+
namespace: this.baseName,
|
|
88
|
+
...metadata
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
warn(message, metadata) {
|
|
92
|
+
this.logger.warn(message, {
|
|
93
|
+
namespace: `${this.baseName}:warning`,
|
|
94
|
+
...metadata
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
error(message, errorContext) {
|
|
98
|
+
const logNamespace = `${this.baseName}:error`;
|
|
99
|
+
if (isSentryEnabled()) {
|
|
100
|
+
const alreadyReported = message instanceof Error && message._sentryReported;
|
|
101
|
+
if (!alreadyReported) {
|
|
102
|
+
const sanitizedContext = this.sanitizeContextForSentry(errorContext);
|
|
103
|
+
const errorMessage = message instanceof Error ? message.message : typeof message === "string" ? message : JSON.stringify(message);
|
|
104
|
+
reportMessageToSentry(errorMessage, "error", {
|
|
105
|
+
errorContext: sanitizedContext,
|
|
106
|
+
logger_name: this.baseName,
|
|
107
|
+
source: "logger"
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (message instanceof Error) {
|
|
112
|
+
this.logger.error(message.message, {
|
|
113
|
+
namespace: logNamespace,
|
|
114
|
+
stack: message.stack,
|
|
115
|
+
name: message.name,
|
|
116
|
+
...message.code && {
|
|
117
|
+
code: message.code
|
|
118
|
+
},
|
|
119
|
+
...message.statusCode && {
|
|
120
|
+
statusCode: message.statusCode
|
|
121
|
+
},
|
|
122
|
+
...errorContext
|
|
123
|
+
});
|
|
124
|
+
} else {
|
|
125
|
+
const logMessage = typeof message === "string" ? message : JSON.stringify(message, null, 2);
|
|
126
|
+
this.logger.error(logMessage, {
|
|
127
|
+
namespace: logNamespace,
|
|
128
|
+
...errorContext
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catchError(error, context) {
|
|
133
|
+
const logNamespace = `${this.baseName}:error`;
|
|
134
|
+
if (isSentryEnabled()) {
|
|
135
|
+
const alreadyReported = error instanceof Error && error._sentryReported;
|
|
136
|
+
if (!alreadyReported) {
|
|
137
|
+
const sanitizedContext = this.sanitizeContextForSentry(context);
|
|
138
|
+
let errorMessage = "Unknown error";
|
|
139
|
+
if (isAxiosError(error)) {
|
|
140
|
+
errorMessage = `Axios Error: ${error.message}`;
|
|
141
|
+
} else if (error instanceof Error) {
|
|
142
|
+
errorMessage = error.message;
|
|
143
|
+
} else if (typeof error === "string") {
|
|
144
|
+
errorMessage = error;
|
|
145
|
+
}
|
|
146
|
+
reportMessageToSentry(errorMessage, "error", {
|
|
147
|
+
errorContext: sanitizedContext,
|
|
148
|
+
logger_name: this.baseName,
|
|
149
|
+
source: "logger"
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (isAxiosError(error)) {
|
|
154
|
+
const errorMessage = `Axios Error: ${error.message}`;
|
|
155
|
+
const errorDetails = {
|
|
156
|
+
namespace: logNamespace,
|
|
157
|
+
type: "AxiosError",
|
|
158
|
+
url: error.config?.url,
|
|
159
|
+
method: error.config?.method?.toUpperCase(),
|
|
160
|
+
status: error.response?.status,
|
|
161
|
+
statusText: error.response?.statusText,
|
|
162
|
+
code: error.code,
|
|
163
|
+
stack: error.stack,
|
|
164
|
+
responseData: error.response?.data,
|
|
165
|
+
requestHeaders: error.config?.headers,
|
|
166
|
+
...context
|
|
167
|
+
};
|
|
168
|
+
this.logger.error(errorMessage, errorDetails);
|
|
169
|
+
} else if (error instanceof Error) {
|
|
170
|
+
const errorDetails = {
|
|
171
|
+
namespace: logNamespace,
|
|
172
|
+
type: error.constructor.name,
|
|
173
|
+
name: error.name,
|
|
174
|
+
stack: error.stack,
|
|
175
|
+
...error.code && {
|
|
176
|
+
code: error.code
|
|
177
|
+
},
|
|
178
|
+
...error.statusCode && {
|
|
179
|
+
statusCode: error.statusCode
|
|
180
|
+
},
|
|
181
|
+
...error.context && {
|
|
182
|
+
errorContext: error.context
|
|
183
|
+
},
|
|
184
|
+
...context
|
|
185
|
+
};
|
|
186
|
+
this.logger.error(error.message, errorDetails);
|
|
187
|
+
} else if (typeof error === "string") {
|
|
188
|
+
this.logger.error(error, {
|
|
189
|
+
namespace: logNamespace,
|
|
190
|
+
type: "String",
|
|
191
|
+
...context
|
|
192
|
+
});
|
|
193
|
+
} else {
|
|
194
|
+
const errorMessage = "Unknown error occurred";
|
|
195
|
+
const serializedError = this.safeStringify(error);
|
|
196
|
+
this.logger.error(errorMessage, {
|
|
197
|
+
namespace: logNamespace,
|
|
198
|
+
type: "Unknown",
|
|
199
|
+
originalError: serializedError,
|
|
200
|
+
...context
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
safeStringify(obj) {
|
|
205
|
+
try {
|
|
206
|
+
return JSON.stringify(obj, this.getCircularReplacer(), 2);
|
|
207
|
+
} catch (error) {
|
|
208
|
+
return `[Unable to stringify: ${String(obj)}]`;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
getCircularReplacer() {
|
|
212
|
+
const seen = new WeakSet();
|
|
213
|
+
return (_key, value)=>{
|
|
214
|
+
if (typeof value === "object" && value !== null) {
|
|
215
|
+
if (seen.has(value)) {
|
|
216
|
+
return "[Circular]";
|
|
217
|
+
}
|
|
218
|
+
seen.add(value);
|
|
219
|
+
}
|
|
220
|
+
return value;
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
sanitizeContextForSentry(context) {
|
|
224
|
+
if (!context) {
|
|
225
|
+
return context;
|
|
226
|
+
}
|
|
227
|
+
try {
|
|
228
|
+
const sanitized = JSON.parse(JSON.stringify(context, this.getCircularReplacer()));
|
|
229
|
+
return sanitized;
|
|
230
|
+
} catch (error) {
|
|
231
|
+
return {
|
|
232
|
+
_sanitizationError: "Failed to sanitize context"
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
extend(extensionName) {
|
|
237
|
+
const extendedName = `${this.baseName}:${extensionName}`;
|
|
238
|
+
return new Log(extendedName);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
//# sourceMappingURL=Logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/utils/Logger.ts"],"sourcesContent":["import { isAxiosError } from \"axios\";\nimport { createLogger, format, transports, Logger } from \"winston\";\nimport { isSentryEnabled, reportMessageToSentry } from \"./SentryUtil.js\";\n\nfunction safeStringify(value: unknown): string {\n const seen = new WeakSet();\n return JSON.stringify(value, (key, val) => {\n // drop known circular/noisy fields from axios\n if (key === 'request' || key === 'socket' || key === '_httpMessage') return undefined;\n if (key === 'config' && val && typeof val === 'object') {\n // pick only safe axios config fields\n const { url, method, headers, params, data, timeout } = val as any;\n return { url, method, headers, params, data, timeout };\n }\n if (key === 'response' && val && typeof val === 'object') {\n const { status, statusText, headers, data } = val as any;\n return { status, statusText, headers, data };\n }\n if (typeof val === 'object' && val !== null) {\n if (seen.has(val)) return '[Circular]';\n seen.add(val);\n }\n return val;\n }, 2);\n}\n\nexport class Log {\n private static instance: Log | null = null;\n private readonly logger: Logger;\n private readonly baseName: string;\n\n private constructor(baseName: string) {\n this.baseName = baseName;\n\n const isProduction = process.env.ENVIRONMENT === \"production\";\n\n const logFormat = format.printf(({ level, message, timestamp, stack, ...meta }) => {\n const namespace = isProduction\n ? this.baseName\n : level === \"error\"\n ? `\\x1b[31m${this.baseName}\\x1b[39m`\n : `\\x1b[35m${this.baseName}\\x1b[39m`;\n\n const { namespace: _, level: __, message: ___, timestamp: ____, stack: _____, ...rest } = meta;\n\n let output = `${timestamp ? `[${timestamp}] ` : \"\"}${namespace} ${message}`;\n\n delete (rest as any).name;\n delete (rest as any).code;\n delete (rest as any).statusCode;\n\n if (Object.keys(rest).length > 0) {\n output += ` ${safeStringify(rest)}`;\n }\n\n if (stack) output += `\\n${stack}`;\n return output;\n });\n\n this.logger = createLogger({\n level: \"debug\",\n format: format.combine(\n format.timestamp({ format: \"YYYY-MM-DD HH:mm:ss\" }),\n format.errors({ stack: true }), // This ensures stack traces are captured\n logFormat,\n ),\n transports: [new transports.Console()],\n });\n }\n\n public static getInstance(): Log {\n if (!Log.instance) {\n const baseName =\n \"@90DC:\" +\n (process.env.npm_package_name || \"package-name-not-specified\");\n Log.instance = new Log(baseName);\n }\n return Log.instance;\n }\n\n public static extendInstance(name: string) {\n return this.getInstance().extend(name);\n }\n\n public debug(message: string, metadata?: any): void {\n this.logger.debug(message, {\n namespace: this.baseName,\n ...metadata,\n });\n }\n\n public info(message: string, metadata?: any): void {\n this.logger.info(message, {\n namespace: this.baseName,\n ...metadata,\n });\n }\n\n public warn(message: string, metadata?: any): void {\n this.logger.warn(message, {\n namespace: `${this.baseName}:warning`,\n ...metadata,\n });\n }\n\n public error(message: unknown, errorContext?: any): void {\n const logNamespace = `${this.baseName}:error`;\n\n if (isSentryEnabled()) {\n const alreadyReported =\n message instanceof Error && (message as any)._sentryReported;\n\n if (!alreadyReported) {\n const sanitizedContext = this.sanitizeContextForSentry(errorContext);\n const errorMessage =\n message instanceof Error\n ? message.message\n : typeof message === \"string\"\n ? message\n : JSON.stringify(message);\n\n reportMessageToSentry(errorMessage, \"error\", {\n errorContext: sanitizedContext,\n logger_name: this.baseName,\n source: \"logger\",\n });\n }\n }\n\n if (message instanceof Error) {\n this.logger.error(message.message, {\n namespace: logNamespace,\n stack: message.stack,\n name: message.name,\n ...((message as any).code && { code: (message as any).code }),\n ...((message as any).statusCode && {\n statusCode: (message as any).statusCode,\n }),\n ...errorContext,\n });\n } else {\n const logMessage =\n typeof message === \"string\"\n ? message\n : JSON.stringify(message, null, 2);\n this.logger.error(logMessage, {\n namespace: logNamespace,\n ...errorContext,\n });\n }\n }\n\n public catchError(error: unknown, context?: any): void {\n const logNamespace = `${this.baseName}:error`;\n\n if (isSentryEnabled()) {\n const alreadyReported =\n error instanceof Error && (error as any)._sentryReported;\n\n if (!alreadyReported) {\n const sanitizedContext = this.sanitizeContextForSentry(context);\n let errorMessage = \"Unknown error\";\n\n if (isAxiosError(error)) {\n errorMessage = `Axios Error: ${error.message}`;\n } else if (error instanceof Error) {\n errorMessage = error.message;\n } else if (typeof error === \"string\") {\n errorMessage = error;\n }\n\n reportMessageToSentry(errorMessage, \"error\", {\n errorContext: sanitizedContext,\n logger_name: this.baseName,\n source: \"logger\",\n });\n }\n }\n\n if (isAxiosError(error)) {\n const errorMessage = `Axios Error: ${error.message}`;\n const errorDetails = {\n namespace: logNamespace,\n type: \"AxiosError\",\n url: error.config?.url,\n method: error.config?.method?.toUpperCase(),\n status: error.response?.status,\n statusText: error.response?.statusText,\n code: error.code,\n stack: error.stack,\n responseData: error.response?.data,\n requestHeaders: error.config?.headers,\n ...context,\n };\n\n this.logger.error(errorMessage, errorDetails);\n } else if (error instanceof Error) {\n const errorDetails = {\n namespace: logNamespace,\n type: error.constructor.name,\n name: error.name,\n stack: error.stack,\n ...((error as any).code && { code: (error as any).code }),\n ...((error as any).statusCode && {\n statusCode: (error as any).statusCode,\n }),\n ...((error as any).context && {\n errorContext: (error as any).context,\n }),\n ...context,\n };\n\n this.logger.error(error.message, errorDetails);\n } else if (typeof error === \"string\") {\n this.logger.error(error, {\n namespace: logNamespace,\n type: \"String\",\n ...context,\n });\n } else {\n const errorMessage = \"Unknown error occurred\";\n const serializedError = this.safeStringify(error);\n\n this.logger.error(errorMessage, {\n namespace: logNamespace,\n type: \"Unknown\",\n originalError: serializedError,\n ...context,\n });\n }\n }\n\n private safeStringify(obj: unknown): string {\n try {\n return JSON.stringify(obj, this.getCircularReplacer(), 2);\n } catch (error) {\n return `[Unable to stringify: ${String(obj)}]`;\n }\n }\n\n private getCircularReplacer() {\n const seen = new WeakSet();\n return (_key: string, value: any) => {\n if (typeof value === \"object\" && value !== null) {\n if (seen.has(value)) {\n return \"[Circular]\";\n }\n seen.add(value);\n }\n return value;\n };\n }\n\n private sanitizeContextForSentry(context: any): any {\n if (!context) {\n return context;\n }\n\n try {\n const sanitized = JSON.parse(JSON.stringify(context, this.getCircularReplacer()));\n return sanitized;\n } catch (error) {\n return { _sanitizationError: \"Failed to sanitize context\" };\n }\n }\n\n public extend(extensionName: string): Log {\n const extendedName = `${this.baseName}:${extensionName}`;\n return new Log(extendedName);\n }\n}"],"names":["isAxiosError","createLogger","format","transports","isSentryEnabled","reportMessageToSentry","safeStringify","value","seen","WeakSet","JSON","stringify","key","val","undefined","url","method","headers","params","data","timeout","status","statusText","has","add","Log","instance","logger","baseName","isProduction","process","env","ENVIRONMENT","logFormat","printf","level","message","timestamp","stack","meta","namespace","_","__","___","____","_____","rest","output","name","code","statusCode","Object","keys","length","combine","errors","Console","getInstance","npm_package_name","extendInstance","extend","debug","metadata","info","warn","error","errorContext","logNamespace","alreadyReported","Error","_sentryReported","sanitizedContext","sanitizeContextForSentry","errorMessage","logger_name","source","logMessage","catchError","context","errorDetails","type","config","toUpperCase","response","responseData","requestHeaders","serializedError","originalError","obj","getCircularReplacer","String","_key","sanitized","parse","_sanitizationError","extensionName","extendedName"],"mappings":"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"}
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
/**
|
|
3
|
+
* NotificationClient
|
|
4
|
+
*
|
|
5
|
+
* Provides methods to interact with the notification service via HTTP API.
|
|
6
|
+
* This allows services to send notifications without direct database access
|
|
7
|
+
* or code duplication.
|
|
8
|
+
*/ export class NotificationClient {
|
|
9
|
+
client;
|
|
10
|
+
/**
|
|
11
|
+
* Create a new notification client
|
|
12
|
+
*
|
|
13
|
+
* @param config - Client configuration with base URL and optional settings
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const notificationClient = new NotificationClient({
|
|
18
|
+
* baseURL: 'http://localhost:3037',
|
|
19
|
+
* timeout: 5000
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*/ constructor(config){
|
|
23
|
+
this.client = axios.create({
|
|
24
|
+
baseURL: config.baseURL,
|
|
25
|
+
timeout: config.timeout || 10000,
|
|
26
|
+
headers: {
|
|
27
|
+
"Content-Type": "application/json",
|
|
28
|
+
...config.headers
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
// ==================== Push Notification Methods ====================
|
|
33
|
+
/**
|
|
34
|
+
* Schedule a push notification for a specific user
|
|
35
|
+
*
|
|
36
|
+
* @param payload - Notification details including user UUID and notification type
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* await client.scheduleNotification({
|
|
41
|
+
* userUuid: '123e4567-e89b-12d3-a456-426614174000',
|
|
42
|
+
* name: 'workout_reminder'
|
|
43
|
+
* });
|
|
44
|
+
* ```
|
|
45
|
+
*/ async scheduleNotification(payload) {
|
|
46
|
+
try {
|
|
47
|
+
await this.client.post("/notifications/save-job", payload);
|
|
48
|
+
} catch (error) {
|
|
49
|
+
this.handleError("Failed to schedule notification", error);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async sendToUser(userUuid, notification) {
|
|
53
|
+
try {
|
|
54
|
+
const response = await this.client.post("/notifications/send-to-user", {
|
|
55
|
+
userUuid,
|
|
56
|
+
notification
|
|
57
|
+
});
|
|
58
|
+
return response.data.messageId;
|
|
59
|
+
} catch (error) {
|
|
60
|
+
this.handleError("Failed to send notification to user", error);
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Send notification to multiple users in batch
|
|
66
|
+
*
|
|
67
|
+
* @param userUuids - Array of user UUIDs
|
|
68
|
+
* @param notification - Notification content
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```typescript
|
|
72
|
+
* await client.sendToUsers(['uuid1', 'uuid2'], {
|
|
73
|
+
* title: 'New Feature',
|
|
74
|
+
* body: 'Check out what's new!'
|
|
75
|
+
* });
|
|
76
|
+
* ```
|
|
77
|
+
*/ async sendToUsers(userUuids, notification) {
|
|
78
|
+
try {
|
|
79
|
+
await this.client.post("/notifications/send-to-users", {
|
|
80
|
+
userUuids,
|
|
81
|
+
notification
|
|
82
|
+
});
|
|
83
|
+
} catch (error) {
|
|
84
|
+
this.handleError("Failed to send batch notification", error);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Send notification to all users
|
|
89
|
+
*
|
|
90
|
+
* @param notification - Notification content
|
|
91
|
+
* @returns Total number of users notified
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```typescript
|
|
95
|
+
* const totalSent = await client.sendToAllUsers({
|
|
96
|
+
* title: 'System Update',
|
|
97
|
+
* body: 'App will be updated soon'
|
|
98
|
+
* });
|
|
99
|
+
* ```
|
|
100
|
+
*/ async sendToAllUsers(notification) {
|
|
101
|
+
try {
|
|
102
|
+
const response = await this.client.post("/notifications/send-to-all", {
|
|
103
|
+
notification
|
|
104
|
+
});
|
|
105
|
+
return response.data.totalSent;
|
|
106
|
+
} catch (error) {
|
|
107
|
+
this.handleError("Failed to send to all users", error);
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Send a push notification to a specific group of users
|
|
113
|
+
*
|
|
114
|
+
* @param request - Group notification request with target group and message
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```typescript
|
|
118
|
+
* await client.sendGroupNotification({
|
|
119
|
+
* group: NotificationGroups.PREMIUM,
|
|
120
|
+
* notification: {
|
|
121
|
+
* title: 'New Feature!',
|
|
122
|
+
* body: 'Check out our new workout plans'
|
|
123
|
+
* }
|
|
124
|
+
* });
|
|
125
|
+
* ```
|
|
126
|
+
*/ async sendGroupNotification(request) {
|
|
127
|
+
try {
|
|
128
|
+
await this.client.post("/notifications/send-group", request);
|
|
129
|
+
} catch (error) {
|
|
130
|
+
this.handleError("Failed to send group notification", error);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// ==================== Email Methods ====================
|
|
134
|
+
/**
|
|
135
|
+
* Schedule an email checkout reminder
|
|
136
|
+
*
|
|
137
|
+
* @param payload - Email reminder details
|
|
138
|
+
*/ async scheduleEmailReminder(payload) {
|
|
139
|
+
try {
|
|
140
|
+
await this.client.post("/notifications/save-email-checkout-reminder", payload);
|
|
141
|
+
} catch (error) {
|
|
142
|
+
this.handleError("Failed to schedule email reminder", error);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Send abandoned cart notification
|
|
147
|
+
*
|
|
148
|
+
* @param payload - Abandoned cart details with user email
|
|
149
|
+
*/ async sendAbandonedCart(payload) {
|
|
150
|
+
try {
|
|
151
|
+
await this.client.post("/notifications/abandoned-cart", payload);
|
|
152
|
+
} catch (error) {
|
|
153
|
+
this.handleError("Failed to send abandoned cart notification", error);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Send password restoration email
|
|
158
|
+
*
|
|
159
|
+
* @param request - Password restoration request
|
|
160
|
+
*/ async sendPasswordRestoration(request) {
|
|
161
|
+
try {
|
|
162
|
+
await this.client.post("/mail/send-password-restoration", request);
|
|
163
|
+
} catch (error) {
|
|
164
|
+
this.handleError("Failed to send password restoration email", error);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Send email confirmation
|
|
169
|
+
*
|
|
170
|
+
* @param request - Email confirmation request
|
|
171
|
+
* @param authToken - User authentication token (required)
|
|
172
|
+
*/ async sendEmailConfirmation(request, authToken) {
|
|
173
|
+
try {
|
|
174
|
+
await this.client.post("/mail/send-confirmation", request, {
|
|
175
|
+
headers: {
|
|
176
|
+
Authorization: `Bearer ${authToken}`
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
} catch (error) {
|
|
180
|
+
this.handleError("Failed to send email confirmation", error);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Send Shopify email
|
|
185
|
+
*
|
|
186
|
+
* @param request - Shopify email details
|
|
187
|
+
*/ async sendShopifyEmail(request) {
|
|
188
|
+
try {
|
|
189
|
+
await this.client.post("/mail/send-shopify-email", request);
|
|
190
|
+
} catch (error) {
|
|
191
|
+
this.handleError("Failed to send Shopify email", error);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Send challenge friend invitation email
|
|
196
|
+
*
|
|
197
|
+
* @param request - Challenge friend request
|
|
198
|
+
*/ async sendChallengeFriendEmail(request) {
|
|
199
|
+
try {
|
|
200
|
+
await this.client.post("/mail/send-challenge-email", request);
|
|
201
|
+
} catch (error) {
|
|
202
|
+
this.handleError("Failed to send challenge email", error);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Send account deletion email
|
|
207
|
+
*
|
|
208
|
+
* @param authToken - User authentication token (required)
|
|
209
|
+
*/ async sendDeleteAccountEmail(authToken) {
|
|
210
|
+
try {
|
|
211
|
+
await this.client.post("/mail/send-delete-email", {}, {
|
|
212
|
+
headers: {
|
|
213
|
+
Authorization: `Bearer ${authToken}`
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
} catch (error) {
|
|
217
|
+
this.handleError("Failed to send delete account email", error);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Send export finished email
|
|
222
|
+
*
|
|
223
|
+
* @param authToken - User authentication token (required)
|
|
224
|
+
*/ async sendExportFinishedEmail(authToken) {
|
|
225
|
+
try {
|
|
226
|
+
await this.client.post("/mail/send-export-finished-email", {}, {
|
|
227
|
+
headers: {
|
|
228
|
+
Authorization: `Bearer ${authToken}`
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
} catch (error) {
|
|
232
|
+
this.handleError("Failed to send export finished email", error);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Send student questionnaire response to coach
|
|
237
|
+
*
|
|
238
|
+
* @param to - Coach email address
|
|
239
|
+
* @param subject - Email subject line
|
|
240
|
+
* @param html - HTML content of the email
|
|
241
|
+
*/ async sendStudentResponseToCoach(params) {
|
|
242
|
+
try {
|
|
243
|
+
await this.client.post("/mail/send-student-response-to-coach", params);
|
|
244
|
+
} catch (error) {
|
|
245
|
+
this.handleError("Failed to send student response to coach", error);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// ==================== Notification Management Methods ====================
|
|
249
|
+
/**
|
|
250
|
+
* Create a new notification template
|
|
251
|
+
*
|
|
252
|
+
* @param request - Notification template details
|
|
253
|
+
* @returns The created notification UUID
|
|
254
|
+
*/ async createNotification(request) {
|
|
255
|
+
try {
|
|
256
|
+
const response = await this.client.post("/notifications/create-notification", request);
|
|
257
|
+
return response.data.uuid;
|
|
258
|
+
} catch (error) {
|
|
259
|
+
this.handleError("Failed to create notification", error);
|
|
260
|
+
throw error;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Create a notification translation
|
|
265
|
+
*
|
|
266
|
+
* @param request - Translation details
|
|
267
|
+
*/ async createNotificationTranslation(request) {
|
|
268
|
+
try {
|
|
269
|
+
await this.client.post("/notifications/create-notification-translation", request);
|
|
270
|
+
} catch (error) {
|
|
271
|
+
this.handleError("Failed to create notification translation", error);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Update a notification template
|
|
276
|
+
*
|
|
277
|
+
* @param request - Updated notification details
|
|
278
|
+
*/ async updateNotification(request) {
|
|
279
|
+
try {
|
|
280
|
+
await this.client.put("/notifications/update-notification", request);
|
|
281
|
+
} catch (error) {
|
|
282
|
+
this.handleError("Failed to update notification", error);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Update a notification translation
|
|
287
|
+
*
|
|
288
|
+
* @param request - Updated translation details
|
|
289
|
+
*/ async updateNotificationTranslation(request) {
|
|
290
|
+
try {
|
|
291
|
+
await this.client.put("/notifications/update-notification-translation", request);
|
|
292
|
+
} catch (error) {
|
|
293
|
+
this.handleError("Failed to update notification translation", error);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Get all notifications, optionally filtered by language
|
|
298
|
+
*
|
|
299
|
+
* @param language - Optional language code to filter translations
|
|
300
|
+
* @returns Array of notifications with translations
|
|
301
|
+
*/ async getNotifications(language) {
|
|
302
|
+
try {
|
|
303
|
+
const url = language ? `/notifications/get-notifications/${language}` : "/notifications/get-notifications";
|
|
304
|
+
const response = await this.client.get(url);
|
|
305
|
+
return response.data;
|
|
306
|
+
} catch (error) {
|
|
307
|
+
this.handleError("Failed to get notifications", error);
|
|
308
|
+
throw error;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Delete a notification or translation
|
|
313
|
+
*
|
|
314
|
+
* @param uuid - Notification UUID
|
|
315
|
+
* @param language - Optional language code to delete only translation
|
|
316
|
+
*/ async deleteNotification(uuid, language) {
|
|
317
|
+
try {
|
|
318
|
+
const params = language ? {
|
|
319
|
+
language
|
|
320
|
+
} : {};
|
|
321
|
+
await this.client.delete(`/notifications/delete-notifications/${uuid}`, {
|
|
322
|
+
params
|
|
323
|
+
});
|
|
324
|
+
} catch (error) {
|
|
325
|
+
this.handleError("Failed to delete notification", error);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
// ==================== Coaching Reminder Methods ====================
|
|
329
|
+
async scheduleCheckinReminder(params, authToken) {
|
|
330
|
+
try {
|
|
331
|
+
await this.client.post("/schedule", params, authToken ? {
|
|
332
|
+
headers: {
|
|
333
|
+
Authorization: `Bearer ${authToken}`
|
|
334
|
+
}
|
|
335
|
+
} : {});
|
|
336
|
+
} catch (error) {
|
|
337
|
+
this.handleError("Failed to schedule check-in reminder", error);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
async cancelCheckinReminder(userUuid, authToken) {
|
|
341
|
+
try {
|
|
342
|
+
await this.client.delete(`/schedule/weekly-checkin/${userUuid}`, authToken ? {
|
|
343
|
+
headers: {
|
|
344
|
+
Authorization: `Bearer ${authToken}`
|
|
345
|
+
}
|
|
346
|
+
} : {});
|
|
347
|
+
} catch (error) {
|
|
348
|
+
this.handleError("Failed to cancel check-in reminder", error);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
// ==================== Error Handling ====================
|
|
352
|
+
/**
|
|
353
|
+
* Handle and format errors from notification service
|
|
354
|
+
*/ handleError(message, error) {
|
|
355
|
+
if (axios.isAxiosError(error)) {
|
|
356
|
+
const axiosError = error;
|
|
357
|
+
const status = axiosError.response?.status;
|
|
358
|
+
const data = axiosError.response?.data;
|
|
359
|
+
console.error(`[NotificationClient] ${message}:`, {
|
|
360
|
+
status,
|
|
361
|
+
message: axiosError.message,
|
|
362
|
+
data
|
|
363
|
+
});
|
|
364
|
+
throw new Error(`${message}: ${status ? `HTTP ${status}` : axiosError.message}`);
|
|
365
|
+
}
|
|
366
|
+
console.error(`[NotificationClient] ${message}:`, error);
|
|
367
|
+
throw new Error(`${message}: ${error}`);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
//# sourceMappingURL=NotificationClient.js.map
|