@growsober/sdk 1.0.0

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 (129) hide show
  1. package/README.md +276 -0
  2. package/dist/__tests__/e2e.test.d.ts +7 -0
  3. package/dist/__tests__/e2e.test.js +472 -0
  4. package/dist/api/client.d.ts +11 -0
  5. package/dist/api/client.js +61 -0
  6. package/dist/api/mutations/admin.d.ts +167 -0
  7. package/dist/api/mutations/admin.js +326 -0
  8. package/dist/api/mutations/ambassadors.d.ts +52 -0
  9. package/dist/api/mutations/ambassadors.js +148 -0
  10. package/dist/api/mutations/auth.d.ts +267 -0
  11. package/dist/api/mutations/auth.js +332 -0
  12. package/dist/api/mutations/bookings.d.ts +59 -0
  13. package/dist/api/mutations/bookings.js +143 -0
  14. package/dist/api/mutations/event-chat.d.ts +35 -0
  15. package/dist/api/mutations/event-chat.js +147 -0
  16. package/dist/api/mutations/events.d.ts +87 -0
  17. package/dist/api/mutations/events.js +205 -0
  18. package/dist/api/mutations/grow90.d.ts +36 -0
  19. package/dist/api/mutations/grow90.js +132 -0
  20. package/dist/api/mutations/hubs.d.ts +111 -0
  21. package/dist/api/mutations/hubs.js +240 -0
  22. package/dist/api/mutations/index.d.ts +22 -0
  23. package/dist/api/mutations/index.js +39 -0
  24. package/dist/api/mutations/jack.d.ts +61 -0
  25. package/dist/api/mutations/jack.js +104 -0
  26. package/dist/api/mutations/library.d.ts +67 -0
  27. package/dist/api/mutations/library.js +168 -0
  28. package/dist/api/mutations/map.d.ts +153 -0
  29. package/dist/api/mutations/map.js +181 -0
  30. package/dist/api/mutations/matching.d.ts +130 -0
  31. package/dist/api/mutations/matching.js +204 -0
  32. package/dist/api/mutations/notifications.d.ts +63 -0
  33. package/dist/api/mutations/notifications.js +106 -0
  34. package/dist/api/mutations/offers.d.ts +26 -0
  35. package/dist/api/mutations/offers.js +47 -0
  36. package/dist/api/mutations/subscriptions.d.ts +127 -0
  37. package/dist/api/mutations/subscriptions.js +140 -0
  38. package/dist/api/mutations/support.d.ts +165 -0
  39. package/dist/api/mutations/support.js +307 -0
  40. package/dist/api/mutations/users.d.ts +211 -0
  41. package/dist/api/mutations/users.js +261 -0
  42. package/dist/api/queries/admin.d.ts +257 -0
  43. package/dist/api/queries/admin.js +320 -0
  44. package/dist/api/queries/ambassadors.d.ts +53 -0
  45. package/dist/api/queries/ambassadors.js +98 -0
  46. package/dist/api/queries/auth.d.ts +16 -0
  47. package/dist/api/queries/auth.js +25 -0
  48. package/dist/api/queries/bookings.d.ts +91 -0
  49. package/dist/api/queries/bookings.js +102 -0
  50. package/dist/api/queries/businesses.d.ts +212 -0
  51. package/dist/api/queries/businesses.js +154 -0
  52. package/dist/api/queries/event-chat.d.ts +19 -0
  53. package/dist/api/queries/event-chat.js +75 -0
  54. package/dist/api/queries/events.d.ts +322 -0
  55. package/dist/api/queries/events.js +221 -0
  56. package/dist/api/queries/grow90.d.ts +26 -0
  57. package/dist/api/queries/grow90.js +85 -0
  58. package/dist/api/queries/hubs.d.ts +165 -0
  59. package/dist/api/queries/hubs.js +143 -0
  60. package/dist/api/queries/index.d.ts +23 -0
  61. package/dist/api/queries/index.js +40 -0
  62. package/dist/api/queries/jack.d.ts +63 -0
  63. package/dist/api/queries/jack.js +92 -0
  64. package/dist/api/queries/library.d.ts +132 -0
  65. package/dist/api/queries/library.js +120 -0
  66. package/dist/api/queries/map.d.ts +216 -0
  67. package/dist/api/queries/map.js +278 -0
  68. package/dist/api/queries/matching.d.ts +136 -0
  69. package/dist/api/queries/matching.js +161 -0
  70. package/dist/api/queries/notifications.d.ts +78 -0
  71. package/dist/api/queries/notifications.js +88 -0
  72. package/dist/api/queries/offers.d.ts +91 -0
  73. package/dist/api/queries/offers.js +103 -0
  74. package/dist/api/queries/subscriptions.d.ts +56 -0
  75. package/dist/api/queries/subscriptions.js +73 -0
  76. package/dist/api/queries/support.d.ts +106 -0
  77. package/dist/api/queries/support.js +202 -0
  78. package/dist/api/queries/users.d.ts +293 -0
  79. package/dist/api/queries/users.js +370 -0
  80. package/dist/api/types.d.ts +464 -0
  81. package/dist/api/types.js +9 -0
  82. package/dist/hooks/useAuth.d.ts +5 -0
  83. package/dist/hooks/useAuth.js +39 -0
  84. package/dist/hooks/useUser.d.ts +43 -0
  85. package/dist/hooks/useUser.js +44 -0
  86. package/dist/index.d.ts +36 -0
  87. package/dist/index.js +67 -0
  88. package/package.json +62 -0
  89. package/src/__tests__/e2e.test.ts +502 -0
  90. package/src/api/client.ts +71 -0
  91. package/src/api/mutations/admin.ts +531 -0
  92. package/src/api/mutations/ambassadors.ts +185 -0
  93. package/src/api/mutations/auth.ts +350 -0
  94. package/src/api/mutations/bookings.ts +190 -0
  95. package/src/api/mutations/event-chat.ts +177 -0
  96. package/src/api/mutations/events.ts +273 -0
  97. package/src/api/mutations/grow90.ts +169 -0
  98. package/src/api/mutations/hubs.ts +385 -0
  99. package/src/api/mutations/index.ts +23 -0
  100. package/src/api/mutations/jack.ts +130 -0
  101. package/src/api/mutations/library.ts +212 -0
  102. package/src/api/mutations/map.ts +230 -0
  103. package/src/api/mutations/matching.ts +271 -0
  104. package/src/api/mutations/notifications.ts +114 -0
  105. package/src/api/mutations/offers.ts +73 -0
  106. package/src/api/mutations/subscriptions.ts +162 -0
  107. package/src/api/mutations/support.ts +390 -0
  108. package/src/api/mutations/users.ts +271 -0
  109. package/src/api/queries/admin.ts +480 -0
  110. package/src/api/queries/ambassadors.ts +139 -0
  111. package/src/api/queries/auth.ts +24 -0
  112. package/src/api/queries/bookings.ts +135 -0
  113. package/src/api/queries/businesses.ts +203 -0
  114. package/src/api/queries/event-chat.ts +78 -0
  115. package/src/api/queries/events.ts +272 -0
  116. package/src/api/queries/grow90.ts +98 -0
  117. package/src/api/queries/hubs.ts +211 -0
  118. package/src/api/queries/index.ts +24 -0
  119. package/src/api/queries/jack.ts +127 -0
  120. package/src/api/queries/library.ts +166 -0
  121. package/src/api/queries/map.ts +331 -0
  122. package/src/api/queries/matching.ts +238 -0
  123. package/src/api/queries/notifications.ts +103 -0
  124. package/src/api/queries/offers.ts +136 -0
  125. package/src/api/queries/subscriptions.ts +91 -0
  126. package/src/api/queries/support.ts +235 -0
  127. package/src/api/queries/users.ts +393 -0
  128. package/src/api/types.ts +596 -0
  129. package/src/index.ts +57 -0
@@ -0,0 +1,307 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useCreateCheckIn = useCreateCheckIn;
4
+ exports.useUpdateCheckIn = useUpdateCheckIn;
5
+ exports.useCreateMoodLog = useCreateMoodLog;
6
+ exports.useCreateWin = useCreateWin;
7
+ exports.useCreateHabit = useCreateHabit;
8
+ exports.useUpdateHabit = useUpdateHabit;
9
+ exports.useDeleteHabit = useDeleteHabit;
10
+ exports.useCompleteHabit = useCompleteHabit;
11
+ exports.useCreateReflection = useCreateReflection;
12
+ const react_query_1 = require("@tanstack/react-query");
13
+ const client_1 = require("../client");
14
+ const support_1 = require("../queries/support");
15
+ // ============================================================================
16
+ // MUTATION HOOKS
17
+ // ============================================================================
18
+ /**
19
+ * Create a daily check-in
20
+ *
21
+ * @param options - TanStack Query mutation options
22
+ *
23
+ * @example
24
+ * ```tsx
25
+ * const { mutate, isPending } = useCreateCheckIn();
26
+ *
27
+ * mutate({
28
+ * mood: 8,
29
+ * notes: 'Feeling great today!',
30
+ * triggers: ['stress'],
31
+ * gratitude: ['My support group']
32
+ * });
33
+ * ```
34
+ */
35
+ function useCreateCheckIn(options) {
36
+ const queryClient = (0, react_query_1.useQueryClient)();
37
+ return (0, react_query_1.useMutation)({
38
+ mutationFn: async (data) => {
39
+ const client = (0, client_1.getApiClient)();
40
+ const response = await client.post('/api/v1/support/check-ins', data);
41
+ return response.data;
42
+ },
43
+ onSuccess: (newCheckIn, variables, context) => {
44
+ // Invalidate check-ins list and today's check-in
45
+ queryClient.invalidateQueries({ queryKey: support_1.supportKeys.checkIns() });
46
+ queryClient.invalidateQueries({ queryKey: support_1.supportKeys.checkInToday() });
47
+ queryClient.invalidateQueries({ queryKey: support_1.supportKeys.checkInStreak() });
48
+ // Call user's onSuccess if provided
49
+ },
50
+ ...options,
51
+ });
52
+ }
53
+ /**
54
+ * Update a daily check-in
55
+ *
56
+ * @param options - TanStack Query mutation options
57
+ *
58
+ * @example
59
+ * ```tsx
60
+ * const { mutate, isPending } = useUpdateCheckIn();
61
+ *
62
+ * mutate({
63
+ * id: 'checkin-123',
64
+ * data: {
65
+ * mood: 4,
66
+ * notes: 'Updated notes',
67
+ * }
68
+ * });
69
+ * ```
70
+ */
71
+ function useUpdateCheckIn(options) {
72
+ const queryClient = (0, react_query_1.useQueryClient)();
73
+ return (0, react_query_1.useMutation)({
74
+ mutationFn: async ({ id, data }) => {
75
+ const client = (0, client_1.getApiClient)();
76
+ const response = await client.put(`/api/v1/support/check-ins/${id}`, data);
77
+ return response.data;
78
+ },
79
+ onSuccess: (updatedCheckIn, variables, context) => {
80
+ // Invalidate check-ins list and today's check-in
81
+ queryClient.invalidateQueries({ queryKey: support_1.supportKeys.checkIns() });
82
+ queryClient.invalidateQueries({ queryKey: support_1.supportKeys.checkInToday() });
83
+ queryClient.invalidateQueries({ queryKey: support_1.supportKeys.checkInStreak() });
84
+ },
85
+ ...options,
86
+ });
87
+ }
88
+ /**
89
+ * Create a mood log
90
+ *
91
+ * @param options - TanStack Query mutation options
92
+ *
93
+ * @example
94
+ * ```tsx
95
+ * const { mutate, isPending } = useCreateMoodLog();
96
+ *
97
+ * mutate({
98
+ * mood: 7,
99
+ * notes: 'Feeling optimistic',
100
+ * activities: ['exercise', 'meditation']
101
+ * });
102
+ * ```
103
+ */
104
+ function useCreateMoodLog(options) {
105
+ const queryClient = (0, react_query_1.useQueryClient)();
106
+ return (0, react_query_1.useMutation)({
107
+ mutationFn: async (data) => {
108
+ const client = (0, client_1.getApiClient)();
109
+ const response = await client.post('/api/v1/support/mood', data);
110
+ return response.data;
111
+ },
112
+ onSuccess: (newMoodLog, variables, context) => {
113
+ // Invalidate mood logs list
114
+ queryClient.invalidateQueries({ queryKey: support_1.supportKeys.moodLogs() });
115
+ // Call user's onSuccess if provided
116
+ },
117
+ ...options,
118
+ });
119
+ }
120
+ /**
121
+ * Create a win
122
+ *
123
+ * @param options - TanStack Query mutation options
124
+ *
125
+ * @example
126
+ * ```tsx
127
+ * const { mutate, isPending } = useCreateWin();
128
+ *
129
+ * mutate({
130
+ * title: '30 days sober!',
131
+ * description: 'Hit my first milestone',
132
+ * category: 'sobriety'
133
+ * });
134
+ * ```
135
+ */
136
+ function useCreateWin(options) {
137
+ const queryClient = (0, react_query_1.useQueryClient)();
138
+ return (0, react_query_1.useMutation)({
139
+ mutationFn: async (data) => {
140
+ const client = (0, client_1.getApiClient)();
141
+ const response = await client.post('/api/v1/support/wins', data);
142
+ return response.data;
143
+ },
144
+ onSuccess: (newWin, variables, context) => {
145
+ // Invalidate wins lists
146
+ queryClient.invalidateQueries({ queryKey: support_1.supportKeys.wins() });
147
+ queryClient.invalidateQueries({ queryKey: support_1.supportKeys.winsByCategory() });
148
+ // Call user's onSuccess if provided
149
+ },
150
+ ...options,
151
+ });
152
+ }
153
+ /**
154
+ * Create a habit
155
+ *
156
+ * @param options - TanStack Query mutation options
157
+ *
158
+ * @example
159
+ * ```tsx
160
+ * const { mutate, isPending } = useCreateHabit();
161
+ *
162
+ * mutate({
163
+ * name: 'Morning meditation',
164
+ * description: '10 minutes of mindfulness',
165
+ * frequency: 'daily',
166
+ * targetDays: 7
167
+ * });
168
+ * ```
169
+ */
170
+ function useCreateHabit(options) {
171
+ const queryClient = (0, react_query_1.useQueryClient)();
172
+ return (0, react_query_1.useMutation)({
173
+ mutationFn: async (data) => {
174
+ const client = (0, client_1.getApiClient)();
175
+ const response = await client.post('/api/v1/support/habits', data);
176
+ return response.data;
177
+ },
178
+ onSuccess: (newHabit, variables, context) => {
179
+ // Invalidate habits list
180
+ queryClient.invalidateQueries({ queryKey: support_1.supportKeys.habits() });
181
+ // Call user's onSuccess if provided
182
+ },
183
+ ...options,
184
+ });
185
+ }
186
+ /**
187
+ * Update a habit
188
+ *
189
+ * @param options - TanStack Query mutation options
190
+ *
191
+ * @example
192
+ * ```tsx
193
+ * const { mutate, isPending } = useUpdateHabit();
194
+ *
195
+ * mutate({
196
+ * id: 'habit-123',
197
+ * data: {
198
+ * name: 'Evening meditation',
199
+ * targetDays: 14
200
+ * }
201
+ * });
202
+ * ```
203
+ */
204
+ function useUpdateHabit(options) {
205
+ const queryClient = (0, react_query_1.useQueryClient)();
206
+ return (0, react_query_1.useMutation)({
207
+ mutationFn: async ({ id, data, }) => {
208
+ const client = (0, client_1.getApiClient)();
209
+ const response = await client.put(`/api/v1/support/habits/${id}`, data);
210
+ return response.data;
211
+ },
212
+ onSuccess: (updatedHabit, variables, context) => {
213
+ // Invalidate habits list
214
+ queryClient.invalidateQueries({ queryKey: support_1.supportKeys.habits() });
215
+ // Call user's onSuccess if provided
216
+ },
217
+ ...options,
218
+ });
219
+ }
220
+ /**
221
+ * Delete a habit
222
+ *
223
+ * @param options - TanStack Query mutation options
224
+ *
225
+ * @example
226
+ * ```tsx
227
+ * const { mutate, isPending } = useDeleteHabit();
228
+ *
229
+ * mutate('habit-123');
230
+ * ```
231
+ */
232
+ function useDeleteHabit(options) {
233
+ const queryClient = (0, react_query_1.useQueryClient)();
234
+ return (0, react_query_1.useMutation)({
235
+ mutationFn: async (id) => {
236
+ const client = (0, client_1.getApiClient)();
237
+ await client.delete(`/api/v1/support/habits/${id}`);
238
+ },
239
+ onSuccess: (data, habitId, context) => {
240
+ // Invalidate habits list
241
+ queryClient.invalidateQueries({ queryKey: support_1.supportKeys.habits() });
242
+ // Call user's onSuccess if provided
243
+ },
244
+ ...options,
245
+ });
246
+ }
247
+ /**
248
+ * Complete a habit for today
249
+ *
250
+ * @param options - TanStack Query mutation options
251
+ *
252
+ * @example
253
+ * ```tsx
254
+ * const { mutate, isPending } = useCompleteHabit();
255
+ *
256
+ * mutate('habit-123');
257
+ * ```
258
+ */
259
+ function useCompleteHabit(options) {
260
+ const queryClient = (0, react_query_1.useQueryClient)();
261
+ return (0, react_query_1.useMutation)({
262
+ mutationFn: async (id) => {
263
+ const client = (0, client_1.getApiClient)();
264
+ const response = await client.post(`/api/v1/support/habits/${id}/complete`);
265
+ return response.data;
266
+ },
267
+ onSuccess: (completedHabit, habitId, context) => {
268
+ // Invalidate habits list to show updated completion status
269
+ queryClient.invalidateQueries({ queryKey: support_1.supportKeys.habits() });
270
+ // Call user's onSuccess if provided
271
+ },
272
+ ...options,
273
+ });
274
+ }
275
+ /**
276
+ * Create a reflection
277
+ *
278
+ * @param options - TanStack Query mutation options
279
+ *
280
+ * @example
281
+ * ```tsx
282
+ * const { mutate, isPending } = useCreateReflection();
283
+ *
284
+ * mutate({
285
+ * content: 'Today I learned...',
286
+ * category: 'growth',
287
+ * mood: 8
288
+ * });
289
+ * ```
290
+ */
291
+ function useCreateReflection(options) {
292
+ const queryClient = (0, react_query_1.useQueryClient)();
293
+ return (0, react_query_1.useMutation)({
294
+ mutationFn: async (data) => {
295
+ const client = (0, client_1.getApiClient)();
296
+ const response = await client.post('/api/v1/support/reflections', data);
297
+ return response.data;
298
+ },
299
+ onSuccess: (newReflection, variables, context) => {
300
+ // Invalidate reflections list
301
+ queryClient.invalidateQueries({ queryKey: support_1.supportKeys.reflections() });
302
+ // Call user's onSuccess if provided
303
+ },
304
+ ...options,
305
+ });
306
+ }
307
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VwcG9ydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcGkvbXV0YXRpb25zL3N1cHBvcnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUE0Q0EsNENBd0JDO0FBb0JELDRDQXNCQztBQWtCRCw0Q0FzQkM7QUFrQkQsb0NBdUJDO0FBbUJELHdDQXNCQztBQW9CRCx3Q0FnQ0M7QUFjRCx3Q0FrQkM7QUFjRCw0Q0FtQkM7QUFrQkQsa0RBc0JDO0FBcllELHVEQUsrQjtBQUMvQixzQ0FBeUM7QUFlekMsZ0RBQWlEO0FBRWpELCtFQUErRTtBQUMvRSxpQkFBaUI7QUFDakIsK0VBQStFO0FBRS9FOzs7Ozs7Ozs7Ozs7Ozs7O0dBZ0JHO0FBQ0gsU0FBZ0IsZ0JBQWdCLENBQzlCLE9BR0M7SUFFRCxNQUFNLFdBQVcsR0FBRyxJQUFBLDRCQUFjLEdBQUUsQ0FBQztJQUVyQyxPQUFPLElBQUEseUJBQVcsRUFBQztRQUNqQixVQUFVLEVBQUUsS0FBSyxFQUFFLElBQTBCLEVBQWlDLEVBQUU7WUFDOUUsTUFBTSxNQUFNLEdBQUcsSUFBQSxxQkFBWSxHQUFFLENBQUM7WUFDOUIsTUFBTSxRQUFRLEdBQUcsTUFBTSxNQUFNLENBQUMsSUFBSSxDQUFDLDJCQUEyQixFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3RFLE9BQU8sUUFBUSxDQUFDLElBQUksQ0FBQztRQUN2QixDQUFDO1FBQ0QsU0FBUyxFQUFFLENBQUMsVUFBVSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsRUFBRTtZQUM1QyxpREFBaUQ7WUFDakQsV0FBVyxDQUFDLGlCQUFpQixDQUFDLEVBQUUsUUFBUSxFQUFFLHFCQUFXLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ3BFLFdBQVcsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLFFBQVEsRUFBRSxxQkFBVyxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN4RSxXQUFXLENBQUMsaUJBQWlCLENBQUMsRUFB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cUJBQVcsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFFdkUsb0NBQW9DO1FBQ3RDLENBQUM7UUFDRCxHQUFHLE9BQU87S0FDWCxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgdXNlTXV0YXRpb24sXG4gIHVzZVF1ZXJ5Q2xpZW50LFxuICBVc2VNdXRhdGlvbk9wdGlvbnMsXG4gIFVzZU11dGF0aW9uUmVzdWx0LFxufSBmcm9tICdAdGFuc3RhY2svcmVhY3QtcXVlcnknO1xuaW1wb3J0IHsgZ2V0QXBpQ2xpZW50IH0gZnJvbSAnLi4vY2xpZW50JztcbmltcG9ydCB0eXBlIHtcbiAgRGFpbHlDaGVja0luUmVzcG9uc2UsXG4gIENyZWF0ZUNoZWNrSW5SZXF1ZXN0LFxuICBVcGRhdGVDaGVja0luUmVxdWVzdCxcbiAgTW9vZExvZ1Jlc3BvbnNlLFxuICBDcmVhdGVNb29kTG9nUmVxdWVzdCxcbiAgV2luUmVzcG9uc2UsXG4gIENyZWF0ZVdpblJlcXVlc3QsXG4gIEhhYml0UmVzcG9uc2UsXG4gIENyZWF0ZUhhYml0UmVxdWVzdCxcbiAgVXBkYXRlSGFiaXRSZXF1ZXN0LFxuICBSZWZsZWN0aW9uUmVzcG9uc2UsXG4gIENyZWF0ZVJlZmxlY3Rpb25SZXF1ZXN0LFxufSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBzdXBwb3J0S2V5cyB9IGZyb20gJy4uL3F1ZXJpZXMvc3VwcG9ydCc7XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIE1VVEFUSU9OIEhPT0tTXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogQ3JlYXRlIGEgZGFpbHkgY2hlY2staW5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFRhblN0YWNrIFF1ZXJ5IG11dGF0aW9uIG9wdGlvbnNcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHN4XG4gKiBjb25zdCB7IG11dGF0ZSwgaXNQZW5kaW5nIH0gPSB1c2VDcmVhdGVDaGVja0luKCk7XG4gKlxuICogbXV0YXRlKHtcbiAqICAgbW9vZDogOCxcbiAqICAgbm90ZXM6ICdGZWVsaW5nIGdyZWF0IHRvZGF5IScsXG4gKiAgIHRyaWdnZXJzOiBbJ3N0cmVzcyddLFxuICogICBncmF0aXR1ZGU6IFsnTXkgc3VwcG9ydCBncm91cCddXG4gKiB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlQ3JlYXRlQ2hlY2tJbihcbiAgb3B0aW9ucz86IE9taXQ8XG4gICAgVXNlTXV0YXRpb25PcHRpb25zPERhaWx5Q2hlY2tJblJlc3BvbnNlLCBFcnJvciwgQ3JlYXRlQ2hlY2tJblJlcXVlc3Q+LFxuICAgICdtdXRhdGlvbkZuJ1xuICA+XG4pOiBVc2VNdXRhdGlvblJlc3VsdDxEYWlseUNoZWNrSW5SZXNwb25zZSwgRXJyb3IsIENyZWF0ZUNoZWNrSW5SZXF1ZXN0PiB7XG4gIGNvbnN0IHF1ZXJ5Q2xpZW50ID0gdXNlUXVlcnlDbGllbnQoKTtcblxuICByZXR1cm4gdXNlTXV0YXRpb24oe1xuICAgIG11dGF0aW9uRm46IGFzeW5jIChkYXRhOiBDcmVhdGVDaGVja0luUmVxdWVzdCk6IFByb21pc2U8RGFpbHlDaGVja0luUmVzcG9uc2U+ID0+IHtcbiAgICAgIGNvbnN0IGNsaWVudCA9IGdldEFwaUNsaWVudCgpO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjbGllbnQucG9zdCgnL2FwaS92MS9zdXBwb3J0L2NoZWNrLWlucycsIGRhdGEpO1xuICAgICAgcmV0dXJuIHJlc3BvbnNlLmRhdGE7XG4gICAgfSxcbiAgICBvblN1Y2Nlc3M6IChuZXdDaGVja0luLCB2YXJpYWJsZXMsIGNvbnRleHQpID0+IHtcbiAgICAgIC8vIEludmFsaWRhdGUgY2hlY2staW5zIGxpc3QgYW5kIHRvZGF5J3MgY2hlY2staW5cbiAgICAgIHF1ZXJ5Q2xpZW50LmludmFsaWRhdGVRdWVyaWVzKHsgcXVlcnlLZXk6IHN1cHBvcnRLZXlzLmNoZWNrSW5zKCkgfSk7XG4gICAgICBxdWVyeUNsaWVudC5pbnZhbGlkYXRlUXVlcmllcyh7IHF1ZXJ5S2V5OiBzdXBwb3J0S2V5cy5jaGVja0luVG9kYXkoKSB9KTtcbiAgICAgIHF1ZXJ5Q2xpZW50LmludmFsaWRhdGVRdWVyaWVzKHsgcXVlcnlLZXk6IHN1cHBvcnRLZXlzLmNoZWNrSW5TdHJlYWsoKSB9KTtcblxuICAgICAgLy8gQ2FsbCB1c2VyJ3Mgb25TdWNjZXNzIGlmIHByb3ZpZGVkXG4gICAgfSxcbiAgICAuLi5vcHRpb25zLFxuICB9KTtcbn1cblxuLyoqXG4gKiBVcGRhdGUgYSBkYWlseSBjaGVjay1pblxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gVGFuU3RhY2sgUXVlcnkgbXV0YXRpb24gb3B0aW9uc1xuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c3hcbiAqIGNvbnN0IHsgbXV0YXRlLCBpc1BlbmRpbmcgfSA9IHVzZVVwZGF0ZUNoZWNrSW4oKTtcbiAqXG4gKiBtdXRhdGUoe1xuICogICBpZDogJ2NoZWNraW4tMTIzJyxcbiAqICAgZGF0YToge1xuICogICAgIG1vb2Q6IDQsXG4gKiAgICAgbm90ZXM6ICdVcGRhdGVkIG5vdGVzJyxcbiAqICAgfVxuICogfSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZVVwZGF0ZUNoZWNrSW4oXG4gIG9wdGlvbnM/OiBPbWl0PFxuICAgIFVzZU11dGF0aW9uT3B0aW9uczxEYWlseUNoZWNrSW5SZXNwb25zZSwgRXJyb3IsIHsgaWQ6IHN0cmluZzsgZGF0YTogVXBkYXRlQ2hlY2tJblJlcXVlc3QgfT4sXG4gICAgJ211dGF0aW9uRm4nXG4gID5cbik6IFVzZU11dGF0aW9uUmVzdWx0PERhaWx5Q2hlY2tJblJlc3BvbnNlLCBFcnJvciwgeyBpZDogc3RyaW5nOyBkYXRhOiBVcGRhdGVDaGVja0luUmVxdWVzdCB9PiB7XG4gIGNvbnN0IHF1ZXJ5Q2xpZW50ID0gdXNlUXVlcnlDbGllbnQoKTtcblxuICByZXR1cm4gdXNlTXV0YXRpb24oe1xuICAgIG11dGF0aW9uRm46IGFzeW5jICh7IGlkLCBkYXRhIH06IHsgaWQ6IHN0cmluZzsgZGF0YTogVXBkYXRlQ2hlY2tJblJlcXVlc3QgfSk6IFByb21pc2U8RGFpbHlDaGVja0luUmVzcG9uc2U+ID0+IHtcbiAgICAgIGNvbnN0IGNsaWVudCA9IGdldEFwaUNsaWVudCgpO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjbGllbnQucHV0KGAvYXBpL3YxL3N1cHBvcnQvY2hlY2staW5zLyR7aWR9YCwgZGF0YSk7XG4gICAgICByZXR1cm4gcmVzcG9uc2UuZGF0YTtcbiAgICB9LFxuICAgIG9uU3VjY2VzczogKHVwZGF0ZWRDaGVja0luLCB2YXJpYWJsZXMsIGNvbnRleHQpID0+IHtcbiAgICAgIC8vIEludmFsaWRhdGUgY2hlY2staW5zIGxpc3QgYW5kIHRvZGF5J3MgY2hlY2staW5cbiAgICAgIHF1ZXJ5Q2xpZW50LmludmFsaWRhdGVRdWVyaWVzKHsgcXVlcnlLZXk6IHN1cHBvcnRLZXlzLmNoZWNrSW5zKCkgfSk7XG4gICAgICBxdWVyeUNsaWVudC5pbnZhbGlkYXRlUXVlcmllcyh7IHF1ZXJ5S2V5OiBzdXBwb3J0S2V5cy5jaGVja0luVG9kYXkoKSB9KTtcbiAgICAgIHF1ZXJ5Q2xpZW50LmludmFsaWRhdGVRdWVyaWVzKHsgcXVlcnlLZXk6IHN1cHBvcnRLZXlzLmNoZWNrSW5TdHJlYWsoKSB9KTtcbiAgICB9LFxuICAgIC4uLm9wdGlvbnMsXG4gIH0pO1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIG1vb2QgbG9nXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBUYW5TdGFjayBRdWVyeSBtdXRhdGlvbiBvcHRpb25zXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzeFxuICogY29uc3QgeyBtdXRhdGUsIGlzUGVuZGluZyB9ID0gdXNlQ3JlYXRlTW9vZExvZygpO1xuICpcbiAqIG11dGF0ZSh7XG4gKiAgIG1vb2Q6IDcsXG4gKiAgIG5vdGVzOiAnRmVlbGluZyBvcHRpbWlzdGljJyxcbiAqICAgYWN0aXZpdGllczogWydleGVyY2lzZScsICdtZWRpdGF0aW9uJ11cbiAqIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VDcmVhdGVNb29kTG9nKFxuICBvcHRpb25zPzogT21pdDxcbiAgICBVc2VNdXRhdGlvbk9wdGlvbnM8TW9vZExvZ1Jlc3BvbnNlLCBFcnJvciwgQ3JlYXRlTW9vZExvZ1JlcXVlc3Q+LFxuICAgICdtdXRhdGlvbkZuJ1xuICA+XG4pOiBVc2VNdXRhdGlvblJlc3VsdDxNb29kTG9nUmVzcG9uc2UsIEVycm9yLCBDcmVhdGVNb29kTG9nUmVxdWVzdD4ge1xuICBjb25zdCBxdWVyeUNsaWVudCA9IHVzZVF1ZXJ5Q2xpZW50KCk7XG5cbiAgcmV0dXJuIHVzZU11dGF0aW9uKHtcbiAgICBtdXRhdGlvbkZuOiBhc3luYyAoZGF0YTogQ3JlYXRlTW9vZExvZ1JlcXVlc3QpOiBQcm9taXNlPE1vb2RMb2dSZXNwb25zZT4gPT4ge1xuICAgICAgY29uc3QgY2xpZW50ID0gZ2V0QXBpQ2xpZW50KCk7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNsaWVudC5wb3N0KCcvYXBpL3YxL3N1cHBvcnQvbW9vZCcsIGRhdGEpO1xuICAgICAgcmV0dXJuIHJlc3BvbnNlLmRhdGE7XG4gICAgfSxcbiAgICBvblN1Y2Nlc3M6IChuZXdNb29kTG9nLCB2YXJpYWJsZXMsIGNvbnRleHQpID0+IHtcbiAgICAgIC8vIEludmFsaWRhdGUgbW9vZCBsb2dzIGxpc3RcbiAgICAgIHF1ZXJ5Q2xpZW50LmludmFsaWRhdGVRdWVyaWVzKHsgcXVlcnlLZXk6IHN1cHBvcnRLZXlzLm1vb2RMb2dzKCkgfSk7XG5cbiAgICAgIC8vIENhbGwgdXNlcidzIG9uU3VjY2VzcyBpZiBwcm92aWRlZFxuICAgIH0sXG4gICAgLi4ub3B0aW9ucyxcbiAgfSk7XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgd2luXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBUYW5TdGFjayBRdWVyeSBtdXRhdGlvbiBvcHRpb25zXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzeFxuICogY29uc3QgeyBtdXRhdGUsIGlzUGVuZGluZyB9ID0gdXNlQ3JlYXRlV2luKCk7XG4gKlxuICogbXV0YXRlKHtcbiAqICAgdGl0bGU6ICczMCBkYXlzIHNvYmVyIScsXG4gKiAgIGRlc2NyaXB0aW9uOiAnSGl0IG15IGZpcnN0IG1pbGVzdG9uZScsXG4gKiAgIGNhdGVnb3J5OiAnc29icmlldHknXG4gKiB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlQ3JlYXRlV2luKFxuICBvcHRpb25zPzogT21pdDxcbiAgICBVc2VNdXRhdGlvbk9wdGlvbnM8V2luUmVzcG9uc2UsIEVycm9yLCBDcmVhdGVXaW5SZXF1ZXN0PixcbiAgICAnbXV0YXRpb25GbidcbiAgPlxuKTogVXNlTXV0YXRpb25SZXN1bHQ8V2luUmVzcG9uc2UsIEVycm9yLCBDcmVhdGVXaW5SZXF1ZXN0PiB7XG4gIGNvbnN0IHF1ZXJ5Q2xpZW50ID0gdXNlUXVlcnlDbGllbnQoKTtcblxuICByZXR1cm4gdXNlTXV0YXRpb24oe1xuICAgIG11dGF0aW9uRm46IGFzeW5jIChkYXRhOiBDcmVhdGVXaW5SZXF1ZXN0KTogUHJvbWlzZTxXaW5SZXNwb25zZT4gPT4ge1xuICAgICAgY29uc3QgY2xpZW50ID0gZ2V0QXBpQ2xpZW50KCk7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNsaWVudC5wb3N0KCcvYXBpL3YxL3N1cHBvcnQvd2lucycsIGRhdGEpO1xuICAgICAgcmV0dXJuIHJlc3BvbnNlLmRhdGE7XG4gICAgfSxcbiAgICBvblN1Y2Nlc3M6IChuZXdXaW4sIHZhcmlhYmxlcywgY29udGV4dCkgPT4ge1xuICAgICAgLy8gSW52YWxpZGF0ZSB3aW5zIGxpc3RzXG4gICAgICBxdWVyeUNsaWVudC5pbnZhbGlkYXRlUXVlcmllcyh7IHF1ZXJ5S2V5OiBzdXBwb3J0S2V5cy53aW5zKCkgfSk7XG4gICAgICBxdWVyeUNsaWVudC5pbnZhbGlkYXRlUXVlcmllcyh7IHF1ZXJ5S2V5OiBzdXBwb3J0S2V5cy53aW5zQnlDYXRlZ29yeSgpIH0pO1xuXG4gICAgICAvLyBDYWxsIHVzZXIncyBvblN1Y2Nlc3MgaWYgcHJvdmlkZWRcbiAgICB9LFxuICAgIC4uLm9wdGlvbnMsXG4gIH0pO1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIGhhYml0XG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBUYW5TdGFjayBRdWVyeSBtdXRhdGlvbiBvcHRpb25zXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzeFxuICogY29uc3QgeyBtdXRhdGUsIGlzUGVuZGluZyB9ID0gdXNlQ3JlYXRlSGFiaXQoKTtcbiAqXG4gKiBtdXRhdGUoe1xuICogICBuYW1lOiAnTW9ybmluZyBtZWRpdGF0aW9uJyxcbiAqICAgZGVzY3JpcHRpb246ICcxMCBtaW51dGVzIG9mIG1pbmRmdWxuZXNzJyxcbiAqICAgZnJlcXVlbmN5OiAnZGFpbHknLFxuICogICB0YXJnZXREYXlzOiA3XG4gKiB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlQ3JlYXRlSGFiaXQoXG4gIG9wdGlvbnM/OiBPbWl0PFxuICAgIFVzZU11dGF0aW9uT3B0aW9uczxIYWJpdFJlc3BvbnNlLCBFcnJvciwgQ3JlYXRlSGFiaXRSZXF1ZXN0PixcbiAgICAnbXV0YXRpb25GbidcbiAgPlxuKTogVXNlTXV0YXRpb25SZXN1bHQ8SGFiaXRSZXNwb25zZSwgRXJyb3IsIENyZWF0ZUhhYml0UmVxdWVzdD4ge1xuICBjb25zdCBxdWVyeUNsaWVudCA9IHVzZVF1ZXJ5Q2xpZW50KCk7XG5cbiAgcmV0dXJuIHVzZU11dGF0aW9uKHtcbiAgICBtdXRhdGlvbkZuOiBhc3luYyAoZGF0YTogQ3JlYXRlSGFiaXRSZXF1ZXN0KTogUHJvbWlzZTxIYWJpdFJlc3BvbnNlPiA9PiB7XG4gICAgICBjb25zdCBjbGllbnQgPSBnZXRBcGlDbGllbnQoKTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2xpZW50LnBvc3QoJy9hcGkvdjEvc3VwcG9ydC9oYWJpdHMnLCBkYXRhKTtcbiAgICAgIHJldHVybiByZXNwb25zZS5kYXRhO1xuICAgIH0sXG4gICAgb25TdWNjZXNzOiAobmV3SGFiaXQsIHZhcmlhYmxlcywgY29udGV4dCkgPT4ge1xuICAgICAgLy8gSW52YWxpZGF0ZSBoYWJpdHMgbGlzdFxuICAgICAgcXVlcnlDbGllbnQuaW52YWxpZGF0ZVF1ZXJpZXMoeyBxdWVyeUtleTogc3VwcG9ydEtleXMuaGFiaXRzKCkgfSk7XG5cbiAgICAgIC8vIENhbGwgdXNlcidzIG9uU3VjY2VzcyBpZiBwcm92aWRlZFxuICAgIH0sXG4gICAgLi4ub3B0aW9ucyxcbiAgfSk7XG59XG5cbi8qKlxuICogVXBkYXRlIGEgaGFiaXRcbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFRhblN0YWNrIFF1ZXJ5IG11dGF0aW9uIG9wdGlvbnNcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHN4XG4gKiBjb25zdCB7IG11dGF0ZSwgaXNQZW5kaW5nIH0gPSB1c2VVcGRhdGVIYWJpdCgpO1xuICpcbiAqIG11dGF0ZSh7XG4gKiAgIGlkOiAnaGFiaXQtMTIzJyxcbiAqICAgZGF0YToge1xuICogICAgIG5hbWU6ICdFdmVuaW5nIG1lZGl0YXRpb24nLFxuICogICAgIHRhcmdldERheXM6IDE0XG4gKiAgIH1cbiAqIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VVcGRhdGVIYWJpdChcbiAgb3B0aW9ucz86IE9taXQ8XG4gICAgVXNlTXV0YXRpb25PcHRpb25zPFxuICAgICAgSGFiaXRSZXNwb25zZSxcbiAgICAgIEVycm9yLFxuICAgICAgeyBpZDogc3RyaW5nOyBkYXRhOiBVcGRhdGVIYWJpdFJlcXVlc3QgfVxuICAgID4sXG4gICAgJ211dGF0aW9uRm4nXG4gID5cbik6IFVzZU11dGF0aW9uUmVzdWx0PEhhYml0UmVzcG9uc2UsIEVycm9yLCB7IGlkOiBzdHJpbmc7IGRhdGE6IFVwZGF0ZUhhYml0UmVxdWVzdCB9PiB7XG4gIGNvbnN0IHF1ZXJ5Q2xpZW50ID0gdXNlUXVlcnlDbGllbnQoKTtcblxuICByZXR1cm4gdXNlTXV0YXRpb24oe1xuICAgIG11dGF0aW9uRm46IGFzeW5jICh7XG4gICAgICBpZCxcbiAgICAgIGRhdGEsXG4gICAgfToge1xuICAgICAgaWQ6IHN0cmluZztcbiAgICAgIGRhdGE6IFVwZGF0ZUhhYml0UmVxdWVzdDtcbiAgICB9KTogUHJvbWlzZTxIYWJpdFJlc3BvbnNlPiA9PiB7XG4gICAgICBjb25zdCBjbGllbnQgPSBnZXRBcGlDbGllbnQoKTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2xpZW50LnB1dChgL2FwaS92MS9zdXBwb3J0L2hhYml0cy8ke2lkfWAsIGRhdGEpO1xuICAgICAgcmV0dXJuIHJlc3BvbnNlLmRhdGE7XG4gICAgfSxcbiAgICBvblN1Y2Nlc3M6ICh1cGRhdGVkSGFiaXQsIHZhcmlhYmxlcywgY29udGV4dCkgPT4ge1xuICAgICAgLy8gSW52YWxpZGF0ZSBoYWJpdHMgbGlzdFxuICAgICAgcXVlcnlDbGllbnQuaW52YWxpZGF0ZVF1ZXJpZXMoeyBxdWVyeUtleTogc3VwcG9ydEtleXMuaGFiaXRzKCkgfSk7XG5cbiAgICAgIC8vIENhbGwgdXNlcidzIG9uU3VjY2VzcyBpZiBwcm92aWRlZFxuICAgIH0sXG4gICAgLi4ub3B0aW9ucyxcbiAgfSk7XG59XG5cbi8qKlxuICogRGVsZXRlIGEgaGFiaXRcbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFRhblN0YWNrIFF1ZXJ5IG11dGF0aW9uIG9wdGlvbnNcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHN4XG4gKiBjb25zdCB7IG11dGF0ZSwgaXNQZW5kaW5nIH0gPSB1c2VEZWxldGVIYWJpdCgpO1xuICpcbiAqIG11dGF0ZSgnaGFiaXQtMTIzJyk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZURlbGV0ZUhhYml0KFxuICBvcHRpb25zPzogT21pdDxVc2VNdXRhdGlvbk9wdGlvbnM8dm9pZCwgRXJyb3IsIHN0cmluZz4sICdtdXRhdGlvbkZuJz5cbik6IFVzZU11dGF0aW9uUmVzdWx0PHZvaWQsIEVycm9yLCBzdHJpbmc+IHtcbiAgY29uc3QgcXVlcnlDbGllbnQgPSB1c2VRdWVyeUNsaWVudCgpO1xuXG4gIHJldHVybiB1c2VNdXRhdGlvbih7XG4gICAgbXV0YXRpb25GbjogYXN5bmMgKGlkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgIGNvbnN0IGNsaWVudCA9IGdldEFwaUNsaWVudCgpO1xuICAgICAgYXdhaXQgY2xpZW50LmRlbGV0ZShgL2FwaS92MS9zdXBwb3J0L2hhYml0cy8ke2lkfWApO1xuICAgIH0sXG4gICAgb25TdWNjZXNzOiAoZGF0YSwgaGFiaXRJZCwgY29udGV4dCkgPT4ge1xuICAgICAgLy8gSW52YWxpZGF0ZSBoYWJpdHMgbGlzdFxuICAgICAgcXVlcnlDbGllbnQuaW52YWxpZGF0ZVF1ZXJpZXMoeyBxdWVyeUtleTogc3VwcG9ydEtleXMuaGFiaXRzKCkgfSk7XG5cbiAgICAgIC8vIENhbGwgdXNlcidzIG9uU3VjY2VzcyBpZiBwcm92aWRlZFxuICAgIH0sXG4gICAgLi4ub3B0aW9ucyxcbiAgfSk7XG59XG5cbi8qKlxuICogQ29tcGxldGUgYSBoYWJpdCBmb3IgdG9kYXlcbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFRhblN0YWNrIFF1ZXJ5IG11dGF0aW9uIG9wdGlvbnNcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHN4XG4gKiBjb25zdCB7IG11dGF0ZSwgaXNQZW5kaW5nIH0gPSB1c2VDb21wbGV0ZUhhYml0KCk7XG4gKlxuICogbXV0YXRlKCdoYWJpdC0xMjMnKTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlQ29tcGxldGVIYWJpdChcbiAgb3B0aW9ucz86IE9taXQ8VXNlTXV0YXRpb25PcHRpb25zPEhhYml0UmVzcG9uc2UsIEVycm9yLCBzdHJpbmc+LCAnbXV0YXRpb25Gbic+XG4pOiBVc2VNdXRhdGlvblJlc3VsdDxIYWJpdFJlc3BvbnNlLCBFcnJvciwgc3RyaW5nPiB7XG4gIGNvbnN0IHF1ZXJ5Q2xpZW50ID0gdXNlUXVlcnlDbGllbnQoKTtcblxuICByZXR1cm4gdXNlTXV0YXRpb24oe1xuICAgIG11dGF0aW9uRm46IGFzeW5jIChpZDogc3RyaW5nKTogUHJvbWlzZTxIYWJpdFJlc3BvbnNlPiA9PiB7XG4gICAgICBjb25zdCBjbGllbnQgPSBnZXRBcGlDbGllbnQoKTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2xpZW50LnBvc3QoYC9hcGkvdjEvc3VwcG9ydC9oYWJpdHMvJHtpZH0vY29tcGxldGVgKTtcbiAgICAgIHJldHVybiByZXNwb25zZS5kYXRhO1xuICAgIH0sXG4gICAgb25TdWNjZXNzOiAoY29tcGxldGVkSGFiaXQsIGhhYml0SWQsIGNvbnRleHQpID0+IHtcbiAgICAgIC8vIEludmFsaWRhdGUgaGFiaXRzIGxpc3QgdG8gc2hvdyB1cGRhdGVkIGNvbXBsZXRpb24gc3RhdHVzXG4gICAgICBxdWVyeUNsaWVudC5pbnZhbGlkYXRlUXVlcmllcyh7IHF1ZXJ5S2V5OiBzdXBwb3J0S2V5cy5oYWJpdHMoKSB9KTtcblxuICAgICAgLy8gQ2FsbCB1c2VyJ3Mgb25TdWNjZXNzIGlmIHByb3ZpZGVkXG4gICAgfSxcbiAgICAuLi5vcHRpb25zLFxuICB9KTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSByZWZsZWN0aW9uXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBUYW5TdGFjayBRdWVyeSBtdXRhdGlvbiBvcHRpb25zXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzeFxuICogY29uc3QgeyBtdXRhdGUsIGlzUGVuZGluZyB9ID0gdXNlQ3JlYXRlUmVmbGVjdGlvbigpO1xuICpcbiAqIG11dGF0ZSh7XG4gKiAgIGNvbnRlbnQ6ICdUb2RheSBJIGxlYXJuZWQuLi4nLFxuICogICBjYXRlZ29yeTogJ2dyb3d0aCcsXG4gKiAgIG1vb2Q6IDhcbiAqIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VDcmVhdGVSZWZsZWN0aW9uKFxuICBvcHRpb25zPzogT21pdDxcbiAgICBVc2VNdXRhdGlvbk9wdGlvbnM8UmVmbGVjdGlvblJlc3BvbnNlLCBFcnJvciwgQ3JlYXRlUmVmbGVjdGlvblJlcXVlc3Q+LFxuICAgICdtdXRhdGlvbkZuJ1xuICA+XG4pOiBVc2VNdXRhdGlvblJlc3VsdDxSZWZsZWN0aW9uUmVzcG9uc2UsIEVycm9yLCBDcmVhdGVSZWZsZWN0aW9uUmVxdWVzdD4ge1xuICBjb25zdCBxdWVyeUNsaWVudCA9IHVzZVF1ZXJ5Q2xpZW50KCk7XG5cbiAgcmV0dXJuIHVzZU11dGF0aW9uKHtcbiAgICBtdXRhdGlvbkZuOiBhc3luYyAoZGF0YTogQ3JlYXRlUmVmbGVjdGlvblJlcXVlc3QpOiBQcm9taXNlPFJlZmxlY3Rpb25SZXNwb25zZT4gPT4ge1xuICAgICAgY29uc3QgY2xpZW50ID0gZ2V0QXBpQ2xpZW50KCk7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNsaWVudC5wb3N0KCcvYXBpL3YxL3N1cHBvcnQvcmVmbGVjdGlvbnMnLCBkYXRhKTtcbiAgICAgIHJldHVybiByZXNwb25zZS5kYXRhO1xuICAgIH0sXG4gICAgb25TdWNjZXNzOiAobmV3UmVmbGVjdGlvbiwgdmFyaWFibGVzLCBjb250ZXh0KSA9PiB7XG4gICAgICAvLyBJbnZhbGlkYXRlIHJlZmxlY3Rpb25zIGxpc3RcbiAgICAgIHF1ZXJ5Q2xpZW50LmludmFsaWRhdGVRdWVyaWVzKHsgcXVlcnlLZXk6IHN1cHBvcnRLZXlzLnJlZmxlY3Rpb25zKCkgfSk7XG5cbiAgICAgIC8vIENhbGwgdXNlcidzIG9uU3VjY2VzcyBpZiBwcm92aWRlZFxuICAgIH0sXG4gICAgLi4ub3B0aW9ucyxcbiAgfSk7XG59XG4iXX0=
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Users Mutation Hooks
3
+ *
4
+ * TanStack Query mutation hooks for user-related write operations.
5
+ * These hooks handle user profile updates and onboarding completion.
6
+ *
7
+ * @module api/mutations/users
8
+ */
9
+ import { UseMutationOptions, UseMutationResult } from '@tanstack/react-query';
10
+ import type { UpdateUserRequest, UserResponse } from '../types';
11
+ /**
12
+ * Update current user's profile
13
+ *
14
+ * @description
15
+ * Updates the authenticated user's profile information.
16
+ * This can include name, bio, avatar, location, sober date, and other profile fields.
17
+ * Automatically invalidates relevant user queries to refresh the UI.
18
+ *
19
+ * @endpoint PUT /api/v1/users/me
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * import { useUpdateCurrentUser } from '@growsober/sdk';
24
+ *
25
+ * function EditProfileForm() {
26
+ * const { mutate: updateProfile, isPending, error } = useUpdateCurrentUser({
27
+ * onSuccess: (data) => {
28
+ * toast.success('Profile updated successfully');
29
+ * navigation.goBack();
30
+ * },
31
+ * onError: (error) => {
32
+ * toast.error('Failed to update profile: ' + error.message);
33
+ * },
34
+ * });
35
+ *
36
+ * const handleSubmit = (formData: FormData) => {
37
+ * updateProfile({
38
+ * name: formData.name,
39
+ * bio: formData.bio,
40
+ * avatar: formData.avatar,
41
+ * city: formData.city,
42
+ * soberDate: formData.soberDate,
43
+ * });
44
+ * };
45
+ *
46
+ * return (
47
+ * <form onSubmit={handleSubmit}>
48
+ * <input name="name" />
49
+ * <textarea name="bio" />
50
+ * <button type="submit" disabled={isPending}>
51
+ * {isPending ? 'Saving...' : 'Save Profile'}
52
+ * </button>
53
+ * {error && <p className="error">{error.message}</p>}
54
+ * </form>
55
+ * );
56
+ * }
57
+ * ```
58
+ *
59
+ * @example
60
+ * Update specific fields:
61
+ * ```tsx
62
+ * function AvatarUploader() {
63
+ * const { mutateAsync: updateProfile } = useUpdateCurrentUser();
64
+ *
65
+ * const handleAvatarChange = async (file: File) => {
66
+ * const uploadedUrl = await uploadImage(file);
67
+ * await updateProfile({ avatar: uploadedUrl });
68
+ * toast.success('Avatar updated!');
69
+ * };
70
+ *
71
+ * return <ImagePicker onSelect={handleAvatarChange} />;
72
+ * }
73
+ * ```
74
+ *
75
+ * @example
76
+ * Update sober date:
77
+ * ```tsx
78
+ * function SoberDatePicker() {
79
+ * const { mutate: updateProfile } = useUpdateCurrentUser();
80
+ * const { data: user } = useCurrentUser();
81
+ *
82
+ * const handleDateChange = (date: Date) => {
83
+ * updateProfile({
84
+ * soberDate: date.toISOString(),
85
+ * });
86
+ * };
87
+ *
88
+ * return (
89
+ * <DatePicker
90
+ * value={user?.soberDate}
91
+ * onChange={handleDateChange}
92
+ * />
93
+ * );
94
+ * }
95
+ * ```
96
+ *
97
+ * @param options - TanStack Query mutation options
98
+ * @returns TanStack Query mutation result
99
+ */
100
+ export declare function useUpdateCurrentUser(options?: Omit<UseMutationOptions<UserResponse, Error, UpdateUserRequest>, 'mutationFn'>): UseMutationResult<UserResponse, Error, UpdateUserRequest>;
101
+ /**
102
+ * Complete user onboarding
103
+ *
104
+ * @description
105
+ * Marks the user's onboarding process as complete.
106
+ * This is typically called after a user completes all required onboarding steps
107
+ * (e.g., setting up profile, selecting interests, setting sober date).
108
+ * Updates the user's onboardingCompleted flag and unlocks full app access.
109
+ *
110
+ * @endpoint POST /api/v1/users/me/complete-onboarding
111
+ *
112
+ * @example
113
+ * ```tsx
114
+ * import { useCompleteOnboarding } from '@growsober/sdk';
115
+ *
116
+ * function OnboardingFinalStep() {
117
+ * const { mutate: completeOnboarding, isPending } = useCompleteOnboarding({
118
+ * onSuccess: () => {
119
+ * toast.success('Welcome to GrowSober!');
120
+ * navigation.navigate('Home');
121
+ * },
122
+ * onError: (error) => {
123
+ * toast.error('Failed to complete onboarding: ' + error.message);
124
+ * },
125
+ * });
126
+ *
127
+ * const handleFinish = () => {
128
+ * completeOnboarding();
129
+ * };
130
+ *
131
+ * return (
132
+ * <div>
133
+ * <h1>You're All Set!</h1>
134
+ * <p>Ready to start your sober journey?</p>
135
+ * <button onClick={handleFinish} disabled={isPending}>
136
+ * {isPending ? 'Setting up...' : 'Get Started'}
137
+ * </button>
138
+ * </div>
139
+ * );
140
+ * }
141
+ * ```
142
+ *
143
+ * @example
144
+ * Multi-step onboarding with validation:
145
+ * ```tsx
146
+ * function OnboardingFlow() {
147
+ * const [currentStep, setCurrentStep] = useState(1);
148
+ * const { mutateAsync: completeOnboarding } = useCompleteOnboarding();
149
+ * const { data: user } = useCurrentUser();
150
+ *
151
+ * const handleComplete = async () => {
152
+ * // Validate all required fields are filled
153
+ * if (!user?.name || !user?.soberDate || !user?.city) {
154
+ * toast.error('Please complete all required fields');
155
+ * return;
156
+ * }
157
+ *
158
+ * try {
159
+ * await completeOnboarding();
160
+ * // User will be redirected via onSuccess callback
161
+ * } catch (error) {
162
+ * console.error('Onboarding error:', error);
163
+ * }
164
+ * };
165
+ *
166
+ * return (
167
+ * <div>
168
+ * {currentStep === 1 && <ProfileSetup onNext={() => setCurrentStep(2)} />}
169
+ * {currentStep === 2 && <InterestSelection onNext={() => setCurrentStep(3)} />}
170
+ * {currentStep === 3 && <SoberDateSetup onNext={handleComplete} />}
171
+ * </div>
172
+ * );
173
+ * }
174
+ * ```
175
+ *
176
+ * @example
177
+ * Check onboarding status:
178
+ * ```tsx
179
+ * function AppNavigator() {
180
+ * const { data: user, isLoading } = useCurrentUser();
181
+ *
182
+ * if (isLoading) return <SplashScreen />;
183
+ *
184
+ * // Redirect to onboarding if not completed
185
+ * if (user && !user.onboardingCompleted) {
186
+ * return <OnboardingFlow />;
187
+ * }
188
+ *
189
+ * return <MainApp />;
190
+ * }
191
+ * ```
192
+ *
193
+ * @example
194
+ * With analytics tracking:
195
+ * ```tsx
196
+ * const { mutate: completeOnboarding } = useCompleteOnboarding({
197
+ * onSuccess: (data) => {
198
+ * analytics.track('Onboarding Completed', {
199
+ * userId: data.id,
200
+ * completedAt: new Date().toISOString(),
201
+ * profileComplete: !!data.bio && !!data.avatar,
202
+ * });
203
+ * navigation.navigate('Home');
204
+ * },
205
+ * });
206
+ * ```
207
+ *
208
+ * @param options - TanStack Query mutation options
209
+ * @returns TanStack Query mutation result
210
+ */
211
+ export declare function useCompleteOnboarding(options?: Omit<UseMutationOptions<UserResponse, Error, void>, 'mutationFn'>): UseMutationResult<UserResponse, Error, void>;