waha-shared 1.0.1

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 (135) hide show
  1. package/.DS_Store +0 -0
  2. package/README.md +10 -0
  3. package/__init__.py +0 -0
  4. package/copy.ts +37 -0
  5. package/data/README.md +45 -0
  6. package/data/__init__.py +0 -0
  7. package/data/aslTimestamps.json +192788 -0
  8. package/data/bibleAudios.json +394 -0
  9. package/data/bibleAudios.ts +4 -0
  10. package/data/bibleResources/audioBibleLicenses.json +6235 -0
  11. package/data/bibleResources/bibleBooks.json +6071 -0
  12. package/data/bibleResources/bibleBooks.ts +4 -0
  13. package/data/bibleResources/bibleChaptersList.json +1191 -0
  14. package/data/bibleResources/bibleChaptersList.ts +4 -0
  15. package/data/bibleResources/textBibleLicenses.json +14603 -0
  16. package/data/bibleStatuses.json +9196 -0
  17. package/data/bibleStatuses.ts +4 -0
  18. package/data/bibleTexts.json +527 -0
  19. package/data/bibleTexts.ts +4 -0
  20. package/data/clones.json +13 -0
  21. package/data/countryResources/areas.json +74 -0
  22. package/data/countryResources/areas.ts +4 -0
  23. package/data/countryResources/countries.json +3362 -0
  24. package/data/countryResources/countries.ts +4 -0
  25. package/data/foundationsCurriculums.json +130 -0
  26. package/data/foundationsCurriculums.ts +4 -0
  27. package/data/languageResources/countriesAndLanguages.json +11718 -0
  28. package/data/languageResources/countriesAndLanguages.ts +16 -0
  29. package/data/languageResources/crowdinLanguages.json +2172 -0
  30. package/data/languageResources/iosVoiceOverLanguages.json +64 -0
  31. package/data/languageResources/iso6933LanguageCodes.json +7927 -0
  32. package/data/languageResources/mmsLanguages.json +28164 -0
  33. package/data/languageResources/phoneLanguages.json +1532 -0
  34. package/data/languageResources/phoneLanguages.ts +14 -0
  35. package/data/languages.json +7045 -0
  36. package/data/languages.ts +4 -0
  37. package/data/mediaDurations.json +32364 -0
  38. package/data/mediaDurations.ts +4 -0
  39. package/data/notification.json +69 -0
  40. package/data/notification.ts +4 -0
  41. package/data/numeralMaps.json +26 -0
  42. package/data/numeralMaps.ts +4 -0
  43. package/data/orphanedBibleTexts.json +2747 -0
  44. package/data/questions.json +317 -0
  45. package/data/questions.ts +4 -0
  46. package/data/questionsCurriculums.json +753 -0
  47. package/data/questionsCurriculums.ts +4 -0
  48. package/data/releaseNotes.json +2381 -0
  49. package/data/releaseNotes.ts +4 -0
  50. package/data/schemas/appTranslations.schema.json +802 -0
  51. package/data/schemas/areas.schema.json +76 -0
  52. package/data/schemas/aslTimestamps.schema.json +59 -0
  53. package/data/schemas/bibleAudios.schema.json +37 -0
  54. package/data/schemas/bibleBooks.schema.json +112 -0
  55. package/data/schemas/bibleChapters.schema.json +61 -0
  56. package/data/schemas/bibleStatuses.schema.json +41 -0
  57. package/data/schemas/bibleTexts.schema.json +60 -0
  58. package/data/schemas/clones.schema.json +63 -0
  59. package/data/schemas/countries.schema.json +84 -0
  60. package/data/schemas/foundationsCurriculums.schema.json +20 -0
  61. package/data/schemas/introductionTranslations.schema.json +101 -0
  62. package/data/schemas/languages.schema.json +365 -0
  63. package/data/schemas/mediaDurations.schema.json +41 -0
  64. package/data/schemas/notification.schema.json +111 -0
  65. package/data/schemas/numeralMaps.schema.json +57 -0
  66. package/data/schemas/questionTranslations.schema.json +20 -0
  67. package/data/schemas/questions.schema.json +29 -0
  68. package/data/schemas/questionsCurriculums.schema.json +34 -0
  69. package/data/schemas/releaseNotes.schema.json +21 -0
  70. package/data/schemas/screenshots.schema.json +23 -0
  71. package/data/schemas/setTranslations.schema.json +70 -0
  72. package/data/schemas/sets.schema.json +109 -0
  73. package/data/schemas/topicsCurriculums.schema.json +20 -0
  74. package/data/screenshots.json +17 -0
  75. package/data/screenshots.ts +4 -0
  76. package/data/sets.json +12258 -0
  77. package/data/sets.ts +4 -0
  78. package/data/specialIds.json +72 -0
  79. package/data/specialIds.ts +19 -0
  80. package/data/timings/som.json +9150 -0
  81. package/data/topicsCurriculums.json +131 -0
  82. package/data/topicsCurriculums.ts +4 -0
  83. package/data/typescript/appTranslations.ts +322 -0
  84. package/data/typescript/areas.ts +45 -0
  85. package/data/typescript/aslTimestamps.ts +36 -0
  86. package/data/typescript/bibleAudioAvailableChapters.ts +35 -0
  87. package/data/typescript/bibleAudios.ts +32 -0
  88. package/data/typescript/bibleBookNames.ts +97 -0
  89. package/data/typescript/bibleBooks.ts +63 -0
  90. package/data/typescript/bibleChapters.ts +40 -0
  91. package/data/typescript/bibleStatuses.ts +54 -0
  92. package/data/typescript/bibleTextAvailableChapters.ts +35 -0
  93. package/data/typescript/bibleTexts.ts +63 -0
  94. package/data/typescript/clones.ts +35 -0
  95. package/data/typescript/countries.ts +152 -0
  96. package/data/typescript/foundationsCurriculums.ts +15 -0
  97. package/data/typescript/introductionTranslations.ts +60 -0
  98. package/data/typescript/languages.ts +369 -0
  99. package/data/typescript/mediaDurations.ts +89 -0
  100. package/data/typescript/notification.ts +189 -0
  101. package/data/typescript/numeralMaps.ts +74 -0
  102. package/data/typescript/questionTranslations.ts +6 -0
  103. package/data/typescript/questions.ts +25 -0
  104. package/data/typescript/questionsCurriculums.ts +26 -0
  105. package/data/typescript/releaseNotes.ts +10 -0
  106. package/data/typescript/screenshots.ts +52 -0
  107. package/data/typescript/setTranslations.ts +39 -0
  108. package/data/typescript/sets.ts +105 -0
  109. package/data/typescript/topicsCurriculums.ts +15 -0
  110. package/data/youtube/playlists.json +28 -0
  111. package/data/youtube/videos.json +262 -0
  112. package/data/youtube/videos.ts +2 -0
  113. package/functions/activeCampaign.ts +127 -0
  114. package/functions/bibleChapterUtils.ts +241 -0
  115. package/functions/crowdin.ts +51 -0
  116. package/functions/languages.ts +284 -0
  117. package/functions/scripturePassages.ts +368 -0
  118. package/functions/sets.ts +495 -0
  119. package/package.json +10 -0
  120. package/translations/appTranslations.json +10239 -0
  121. package/translations/appTranslations.ts +4 -0
  122. package/translations/introductionTranslations.json +422 -0
  123. package/translations/introductionTranslations.ts +4 -0
  124. package/translations/questionTranslations.json +1472 -0
  125. package/translations/questionTranslations.ts +4 -0
  126. package/translations/setTranslations.json +30257 -0
  127. package/translations/setTranslations.ts +4 -0
  128. package/translations/spokenQuestionTranslations.json +1472 -0
  129. package/types/analytics.ts +147 -0
  130. package/types/completions.ts +9 -0
  131. package/types/feedback.ts +27 -0
  132. package/types/languages.ts +37 -0
  133. package/types/notifications.ts +37 -0
  134. package/types/sets.ts +84 -0
  135. package/types/users.ts +162 -0
@@ -0,0 +1,147 @@
1
+ import type { ArticleSession, BibleSession, WahaShareContent } from './users'
2
+
3
+ type Meeting =
4
+ | {
5
+ name: 'OpenPlayScreen'
6
+ payload: {
7
+ isLessonDownloaded: boolean
8
+ }
9
+ }
10
+ | {
11
+ name: 'CompleteLesson'
12
+ payload: {
13
+ timeToCompletion: number
14
+ isAudioFacilitator: boolean
15
+ }
16
+ }
17
+ | {
18
+ name: 'ScheduleNextMeeting'
19
+ payload: {
20
+ date: number
21
+ }
22
+ }
23
+ | {
24
+ name: 'LeavePlayScreen'
25
+ payload: {
26
+ sessionLength: number
27
+ endedInCompletion: boolean
28
+ }
29
+ }
30
+ | {
31
+ name: 'DbsCast'
32
+ payload: null
33
+ }
34
+
35
+ type Article = {
36
+ name: 'ArticleSession'
37
+ payload: ArticleSession
38
+ }
39
+
40
+ type Share = {
41
+ name: 'Share'
42
+ payload: {
43
+ content: WahaShareContent
44
+ lessonId?: string
45
+ }
46
+ }
47
+
48
+ type Misc =
49
+ | {
50
+ name: 'UnlockMobilizationTools'
51
+ payload: null
52
+ }
53
+ | {
54
+ name: 'EnableSecurityMode'
55
+ payload: null
56
+ }
57
+ | {
58
+ name: 'ClearStorage'
59
+ payload: {
60
+ languageToClear: string
61
+ }
62
+ }
63
+ | {
64
+ name: 'RequestCode'
65
+ payload: null
66
+ }
67
+ | {
68
+ name: 'ClickGiveButton'
69
+ payload: null
70
+ }
71
+ | {
72
+ name: 'NotificationOptIn'
73
+ payload: {
74
+ enabled: boolean
75
+ }
76
+ }
77
+ | {
78
+ name: 'FinishOnboarding'
79
+ payload: {
80
+ skipped: boolean
81
+ }
82
+ }
83
+ | {
84
+ name: 'ClickNotification'
85
+ payload: {
86
+ id: string
87
+ notificationDate: string
88
+ }
89
+ }
90
+ | {
91
+ name: 'ClickNotificationLink'
92
+ payload: {
93
+ id: string
94
+ notificationDate: string
95
+ }
96
+ }
97
+ | {
98
+ name: 'SetInitialLanguages'
99
+ payload: {
100
+ ipCountry: string
101
+ phoneCountry: string
102
+ languages: string[]
103
+ }
104
+ }
105
+ | {
106
+ name: 'ChangeInitialLanguages'
107
+ payload: {
108
+ ipCountry: string
109
+ phoneCountry: string
110
+ languages: string[]
111
+ }
112
+ }
113
+ | {
114
+ name: 'AskForReview'
115
+ payload: null
116
+ }
117
+
118
+ type Note =
119
+ | {
120
+ name: 'MakeNote'
121
+ payload: null
122
+ }
123
+ | {
124
+ name: 'EditNote'
125
+ payload: null
126
+ }
127
+ | {
128
+ name: 'ViewNotes'
129
+ payload: null
130
+ }
131
+ | {
132
+ name: 'SavedNote'
133
+ payload: {
134
+ length: number
135
+ }
136
+ }
137
+ | {
138
+ name: 'DeleteNote'
139
+ payload: null
140
+ }
141
+
142
+ type Bible = {
143
+ name: 'BibleSession'
144
+ payload: BibleSession
145
+ }
146
+
147
+ export type AnalyticsEvent = Meeting | Share | Misc | Article | Bible | Note
@@ -0,0 +1,9 @@
1
+ import type { CompletionEvent } from './users'
2
+
3
+ export interface SetProgress {
4
+ completionEvents: CompletionEvent[]
5
+ uniqueCompletions: CompletionEvent[]
6
+ total: number
7
+ progress: number
8
+ percent: number
9
+ }
@@ -0,0 +1,27 @@
1
+ import { z } from 'zod'
2
+
3
+ export const FeedbackSchema = z.object({
4
+ language: z.string(),
5
+ appVersion: z.string(),
6
+ OS: z.string(),
7
+ timeSubmitted: z.number(),
8
+ formName: z.string(),
9
+ country: z.string().optional(),
10
+ city: z.string().optional(),
11
+ lessonId: z.string().nullable().optional(),
12
+ wahaUserId: z.string().optional(),
13
+ name: z.string().optional(),
14
+ email: z.string().email(),
15
+ // For the standard contact us form.
16
+ message: z.string().optional(),
17
+ // For the code request form.
18
+ journey: z.union([z.string(), z.record(z.string(), z.boolean())]).optional(),
19
+ goals: z.string().optional(),
20
+ hear: z.string().optional(),
21
+ // For the share story form.
22
+ beforeWaha: z.string().optional(),
23
+ godDone: z.string().optional(),
24
+ findOut: z.string().optional(),
25
+ })
26
+
27
+ export type Feedback = z.infer<typeof FeedbackSchema>
@@ -0,0 +1,37 @@
1
+ import type { BibleAudios } from '../data/typescript/bibleAudios'
2
+ import type { BibleTexts } from '../data/typescript/bibleTexts'
3
+ import type { IntroductionTranslations } from '../data/typescript/introductionTranslations'
4
+ import type { Languages } from '../data/typescript/languages'
5
+ import type { QuestionsCurriculums } from '../data/typescript/questionsCurriculums'
6
+ import type { QuestionTranslations } from '../data/typescript/questionTranslations'
7
+ import type { SetTranslations } from '../data/typescript/setTranslations'
8
+
9
+ type Language = Languages[number]
10
+ type BibleText = BibleTexts[number]
11
+ type BibleAudio = BibleAudios[number]
12
+
13
+ export interface BibleInfo
14
+ extends Omit<BibleText, 'language' | 'copyright'>,
15
+ Omit<BibleAudio, 'language' | 'copyright'> {
16
+ language: Language
17
+ availableTextChapters: string[]
18
+ availableAudioChapters: string[]
19
+ fullCopyright: string
20
+ bookNames: Record<string, string>
21
+ }
22
+
23
+ export interface LanguageInfo
24
+ extends Omit<Language, 'bible' | 'bibleFallback'> {
25
+ sets: string[]
26
+ questionSets: QuestionsCurriculums[number]['questionSets']
27
+ bible: BibleInfo
28
+ bibleFallback: BibleInfo | undefined
29
+ trainingVideoLanguage: string
30
+ isRtl: boolean
31
+ }
32
+
33
+ export interface MeetTranslations {
34
+ sets: SetTranslations[string]
35
+ questions: QuestionTranslations[string]
36
+ introductions: IntroductionTranslations[string]
37
+ }
@@ -0,0 +1,37 @@
1
+ import { notification } from '../data/typescript/notification'
2
+ import { z } from 'zod'
3
+
4
+ export const PushNotificationPayloadSchema = z.object({
5
+ actionUrl: z.string().url().optional(),
6
+ /**
7
+ * We want the full title, not the push title, to be attached to the
8
+ * notification.
9
+ */
10
+ title: z.string(),
11
+ /**
12
+ * We want the full body, not the push body, to be attached to the
13
+ * notification.
14
+ */
15
+ body: z.string(),
16
+ titleSource: z.string(),
17
+ bodySource: z.string(),
18
+ verified: z.boolean(),
19
+ imageUrl: z.string().url().optional(),
20
+ wahaUserId: z.string(),
21
+ date: z.string(),
22
+ })
23
+
24
+ export type PushNotificationPayload = z.infer<
25
+ typeof PushNotificationPayloadSchema
26
+ >
27
+
28
+ export const PushNotificationRecordSchema = z.object({
29
+ date: z.string(),
30
+ notification,
31
+ receivedTokens: z.array(z.string()),
32
+ receivedUserIds: z.array(z.string()),
33
+ })
34
+
35
+ export type PushNotificationRecord = z.infer<
36
+ typeof PushNotificationRecordSchema
37
+ >
package/types/sets.ts ADDED
@@ -0,0 +1,84 @@
1
+ import { type Languages } from '../data/typescript/languages'
2
+ import { type Sets } from '../data/typescript/sets'
3
+
4
+ export type Set = Sets[number]
5
+ export type Lesson = Sets[number]['lessons'][number]
6
+
7
+ export type SetCategory = 'Foundations' | 'Topics' | 'WahaTraining'
8
+
9
+ export interface SetInfo extends Set {
10
+ // Id info.
11
+ meetLanguageId: Languages[number]['languageId']
12
+ category: SetCategory
13
+ setNumber: string
14
+ // Translations.
15
+ setTitle?: string
16
+ setSubtitle: string
17
+ setDescription?: string
18
+ setTag?: string
19
+ setLink: string
20
+ }
21
+
22
+ export interface Content {
23
+ languageId: string
24
+ id: string
25
+ localFileName: string
26
+ remoteFileName: string
27
+ path: string
28
+ url: string
29
+ }
30
+
31
+ interface BaseInfo {
32
+ lessonNumber: string
33
+ // Translations.
34
+ lessonTitle: string | undefined
35
+ lessonIntroduction: string | undefined
36
+ lessonLink: string
37
+ sections: Section[]
38
+ }
39
+
40
+ export interface Section {
41
+ id: string
42
+ header: string | null
43
+ text: string
44
+ isChapter: boolean
45
+ hasBeep: boolean
46
+ index: number
47
+ indexWithinChapter: number
48
+ chapter: Chapter | null
49
+ }
50
+
51
+ export interface DbsInfo extends BaseInfo, SetInfo, Lesson {
52
+ type: 'dbs'
53
+ full: Content
54
+ dbsCast: {
55
+ remoteFileName: string
56
+ url: string
57
+ }
58
+ lessonIntroduction: string | undefined
59
+ passagesString: string
60
+ }
61
+
62
+ export interface VideoInfo extends BaseInfo, SetInfo, Lesson {
63
+ type: 'video'
64
+ video: Content
65
+ lessonSectionHeader: string | undefined
66
+ lessonSectionBody: string | undefined
67
+ youtubeLink: string | undefined
68
+ passagesString: string
69
+ }
70
+
71
+ export interface EqInfo extends BaseInfo, SetInfo, Lesson {
72
+ type: 'eq'
73
+ // text: string
74
+ eq: Content
75
+ }
76
+
77
+ export type LessonInfo = DbsInfo | VideoInfo | EqInfo
78
+
79
+ export enum Chapter {
80
+ FELLOWSHIP = 'f',
81
+ INTRODUCTION = 'i',
82
+ STORY = 's',
83
+ APPLICATION = 'a',
84
+ }
package/types/users.ts ADDED
@@ -0,0 +1,162 @@
1
+ import { z } from 'zod'
2
+
3
+ const WahaUserLocationSchema = z.object({
4
+ city: z.string().optional(),
5
+ country: z.string().optional(),
6
+ region: z.string().optional(),
7
+ })
8
+ export type WahaUserLocation = z.infer<typeof WahaUserLocationSchema>
9
+
10
+ export type WahaAppVersion = `${number}.${number}.${number}`
11
+
12
+ const DesireIdSchema = z.enum([
13
+ 'talk_to_others_about_jesus',
14
+ 'build_a_team_of_disciple_makers',
15
+ 'reach_my_entire_people_or_nation_for_god',
16
+ 'understand_wahas_impact',
17
+ 'understand_how_waha_works',
18
+ 'get_coaching',
19
+ 'see_god_transform_my_community',
20
+ 'discover_whats_in_the_bible',
21
+ 'find_hope_in_my_troubles',
22
+ 'get_right_with_god',
23
+ 'learn_more_about_jesus',
24
+ ])
25
+ export type DesireId = z.infer<typeof DesireIdSchema>
26
+
27
+ const WahaUserStateSchema = z.object({
28
+ wahaUserId: z.string().optional(),
29
+ name: z.string().optional(),
30
+ email: z.string().email().optional(),
31
+ location: WahaUserLocationSchema.optional(),
32
+ pastLocations: z.array(WahaUserLocationSchema).optional(),
33
+ phoneLocation: z.string().optional(),
34
+ isSubscribedToEmailUpdates: z.boolean().optional(),
35
+ pushToken: z.string().optional(),
36
+ notificationPermission: z.enum(['granted', 'undetermined', 'denied']),
37
+ utm: z.record(z.string(), z.string()).optional(),
38
+ firstOpen: z.number().optional(),
39
+ finishedOnboarding: z.number().optional(),
40
+ howFamiliarWithBible: z.number().optional(),
41
+ followingFor2Years: z.number().optional(),
42
+ notificationsClicked: z.number().optional(),
43
+ notificationLinksClicked: z.number().optional(),
44
+ isBeliever: z.boolean().optional(),
45
+ isInAGroup: z.boolean().optional(),
46
+ desires: z.array(DesireIdSchema).optional(),
47
+ customDesire: z.string().optional(),
48
+ isCCWorker: z.boolean().optional(),
49
+ isAdvocate: z.boolean().optional(),
50
+ onboardingStatus: z
51
+ .enum([
52
+ 'skipped-from-first',
53
+ 'skipped-from-second',
54
+ 'finished-from-first',
55
+ 'finished-from-second',
56
+ 'finished-from-languages',
57
+ ])
58
+ .optional(),
59
+ })
60
+
61
+ export type WahaUserState = z.infer<typeof WahaUserStateSchema>
62
+
63
+ const WahaAppVersionSchema = z.string().regex(/^\d+\.\d+\.\d+$/)
64
+
65
+ const CompletionEventSchema = z.object({
66
+ lessonId: z.string(),
67
+ meetLanguageId: z.string(),
68
+ time: z.number(),
69
+ country: z.string().optional(),
70
+ region: z.string().optional(),
71
+ city: z.string().optional(),
72
+ /**
73
+ * Indicates that the lesson was completed manually from the lesson sheet
74
+ * rather than automatically by doing the lesson on the lesson screen.
75
+ */
76
+ manual: z.boolean().optional(),
77
+ })
78
+
79
+ export type CompletionEvent = z.infer<typeof CompletionEventSchema>
80
+
81
+ const WahaShareContentSchema = z.enum([
82
+ 'app',
83
+ 'passcode',
84
+ 'lessonAudio',
85
+ 'lessonText',
86
+ 'storyText',
87
+ 'storyAudio',
88
+ 'lessonLink',
89
+ 'setLink',
90
+ 'meetingInvite',
91
+ 'articleLink',
92
+ 'videoLink',
93
+ 'notification',
94
+ 'meetingSchedule',
95
+ 'scriptureText',
96
+ 'mt',
97
+ 'scriptureAudio',
98
+ 'inviteGroup',
99
+ 'lesson',
100
+ 'offlineVersionLink',
101
+ 'note',
102
+ 'customSet',
103
+ ])
104
+ export type WahaShareContent = z.infer<typeof WahaShareContentSchema>
105
+
106
+ const ShareLogEventSchema = z.object({
107
+ time: z.number(),
108
+ content: WahaShareContentSchema,
109
+ lessonId: z.string().optional(),
110
+ articleSlug: z.string().optional(),
111
+ })
112
+
113
+ export type ShareLogEvent = z.infer<typeof ShareLogEventSchema>
114
+
115
+ const BibleSessionSchema = z.object({
116
+ chapter: z.string(),
117
+ timeSpent: z.number(),
118
+ startTime: z.number(),
119
+ translation: z.string(),
120
+ })
121
+ export type BibleSession = z.infer<typeof BibleSessionSchema>
122
+
123
+ const ArticleSessionSchema = z.object({
124
+ articleSlug: z.string(),
125
+ timeSpent: z.number(),
126
+ startTime: z.number(),
127
+ })
128
+ export type ArticleSession = z.infer<typeof ArticleSessionSchema>
129
+
130
+ // Zod schema for WahaUser extending WahaUserStateSchema
131
+ export const WahaUserSchema = WahaUserStateSchema.extend({
132
+ pushToken: z.string().optional(),
133
+ securityModeOn: z.boolean().optional(),
134
+ appVersion: WahaAppVersionSchema,
135
+ lastUpdate: z.number(),
136
+ platform: z.string(),
137
+ completions: z.array(CompletionEventSchema),
138
+ trainingUnlocked: z.boolean().optional(),
139
+ meet: z.string(),
140
+ appInterface: z.string(),
141
+ meetFavorites: z.array(z.string()),
142
+ osVersion: z.string().nullable(),
143
+ isDev: z.boolean(),
144
+ shareLog: z.array(ShareLogEventSchema).optional(),
145
+ bibleSessions: z.array(BibleSessionSchema).optional(),
146
+ articleSessions: z.array(ArticleSessionSchema).optional(),
147
+ activated: z.boolean().optional(),
148
+ })
149
+
150
+ export const PushEnabledWahaUserSchema = WahaUserSchema.omit({
151
+ wahaUserId: true,
152
+ pushToken: true,
153
+ notificationPermission: true,
154
+ }).extend({
155
+ wahaUserId: z.string(),
156
+ pushToken: z.string(),
157
+ notificationPermission: z.literal('granted'),
158
+ })
159
+ export type PushEnabledWahaUser = z.infer<typeof PushEnabledWahaUserSchema>
160
+
161
+ // Type inferred from the Zod schema
162
+ export type WahaUser = z.infer<typeof WahaUserSchema>