@appgram/react 0.1.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.
package/dist/index.js ADDED
@@ -0,0 +1,783 @@
1
+ 'use strict';
2
+
3
+ var chunkZJZ3A2S3_js = require('./chunk-ZJZ3A2S3.js');
4
+ var chunk3UBJGXCO_js = require('./chunk-3UBJGXCO.js');
5
+ var chunk75P634IK_js = require('./chunk-75P634IK.js');
6
+ var react = require('react');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+
9
+ // src/client/AppgramClient.ts
10
+ var AppgramClient = class {
11
+ constructor(config) {
12
+ this.baseUrl = config.baseUrl.replace(/\/$/, "");
13
+ this.projectId = config.projectId;
14
+ this.orgSlug = config.orgSlug;
15
+ this.projectSlug = config.projectSlug;
16
+ }
17
+ // ============================================================================
18
+ // HTTP Methods
19
+ // ============================================================================
20
+ async request(method, endpoint, options) {
21
+ let url = `${this.baseUrl}${endpoint}`;
22
+ if (options?.params) {
23
+ const searchParams = new URLSearchParams();
24
+ Object.entries(options.params).forEach(([key, value]) => {
25
+ if (value !== void 0 && value !== null && value !== "") {
26
+ searchParams.append(key, value);
27
+ }
28
+ });
29
+ const queryString = searchParams.toString();
30
+ if (queryString) {
31
+ url += `?${queryString}`;
32
+ }
33
+ }
34
+ try {
35
+ const response = await fetch(url, {
36
+ method,
37
+ headers: {
38
+ "Content-Type": "application/json"
39
+ },
40
+ body: options?.body ? JSON.stringify(options.body) : void 0
41
+ });
42
+ const data = await response.json();
43
+ if (!response.ok) {
44
+ return {
45
+ success: false,
46
+ error: {
47
+ code: String(response.status),
48
+ message: data.message || data.error || "An error occurred"
49
+ }
50
+ };
51
+ }
52
+ if (data && typeof data === "object" && "success" in data) {
53
+ return data;
54
+ }
55
+ return {
56
+ success: true,
57
+ data
58
+ };
59
+ } catch (error) {
60
+ return {
61
+ success: false,
62
+ error: {
63
+ code: "NETWORK_ERROR",
64
+ message: error instanceof Error ? error.message : "Network error"
65
+ }
66
+ };
67
+ }
68
+ }
69
+ get(endpoint, params) {
70
+ return this.request("GET", endpoint, { params });
71
+ }
72
+ /**
73
+ * Raw request that returns the API response as-is without transformation
74
+ */
75
+ async requestRaw(endpoint, params) {
76
+ let url = `${this.baseUrl}${endpoint}`;
77
+ if (params) {
78
+ const searchParams = new URLSearchParams();
79
+ Object.entries(params).forEach(([key, value]) => {
80
+ if (value !== void 0 && value !== null && value !== "") {
81
+ searchParams.append(key, value);
82
+ }
83
+ });
84
+ const queryString = searchParams.toString();
85
+ if (queryString) {
86
+ url += `?${queryString}`;
87
+ }
88
+ }
89
+ try {
90
+ const response = await fetch(url, {
91
+ method: "GET",
92
+ headers: {
93
+ "Content-Type": "application/json"
94
+ }
95
+ });
96
+ const data = await response.json();
97
+ if (!response.ok) {
98
+ return {
99
+ success: false,
100
+ error: {
101
+ code: String(response.status),
102
+ message: data.message || data.error || "An error occurred"
103
+ }
104
+ };
105
+ }
106
+ return data;
107
+ } catch (error) {
108
+ return {
109
+ success: false,
110
+ error: {
111
+ code: "NETWORK_ERROR",
112
+ message: error instanceof Error ? error.message : "Network error"
113
+ }
114
+ };
115
+ }
116
+ }
117
+ post(endpoint, body) {
118
+ return this.request("POST", endpoint, { body });
119
+ }
120
+ delete(endpoint) {
121
+ return this.request("DELETE", endpoint);
122
+ }
123
+ // ============================================================================
124
+ // Wishes
125
+ // ============================================================================
126
+ /**
127
+ * Get public wishes for the project
128
+ */
129
+ async getPublicWishes(filters) {
130
+ const params = {
131
+ project_id: this.projectId
132
+ };
133
+ if (filters?.status) {
134
+ params.status = Array.isArray(filters.status) ? filters.status.join(",") : filters.status;
135
+ }
136
+ if (filters?.category_id) params.category_id = filters.category_id;
137
+ if (filters?.search) params.search = filters.search;
138
+ if (filters?.sort_by) params.sort_by = filters.sort_by;
139
+ if (filters?.sort_order) params.sort_order = filters.sort_order;
140
+ if (filters?.page) params.page = String(filters.page);
141
+ if (filters?.per_page) params.per_page = String(filters.per_page);
142
+ if (filters?.fingerprint) params.fingerprint = filters.fingerprint;
143
+ const rawResponse = await this.requestRaw("/portal/wishes", params);
144
+ if (!rawResponse.success) {
145
+ return {
146
+ success: false,
147
+ error: rawResponse.error
148
+ };
149
+ }
150
+ return {
151
+ success: true,
152
+ data: {
153
+ data: rawResponse.data || [],
154
+ total: rawResponse.total || 0,
155
+ page: rawResponse.page || 1,
156
+ per_page: rawResponse.per_page || 20,
157
+ total_pages: rawResponse.total_pages || 0
158
+ }
159
+ };
160
+ }
161
+ /**
162
+ * Get a single wish by ID
163
+ */
164
+ async getWish(wishId) {
165
+ return this.get(`/portal/wishes/${wishId}`, {
166
+ project_id: this.projectId
167
+ });
168
+ }
169
+ /**
170
+ * Create a new wish (feature request)
171
+ */
172
+ async createWish(data) {
173
+ return this.post("/portal/wishes", {
174
+ project_id: this.projectId,
175
+ ...data
176
+ });
177
+ }
178
+ // ============================================================================
179
+ // Votes
180
+ // ============================================================================
181
+ /**
182
+ * Check if a fingerprint has voted on a wish
183
+ */
184
+ async checkVote(wishId, fingerprint) {
185
+ return this.get(`/api/v1/votes/check/${wishId}`, {
186
+ fingerprint
187
+ });
188
+ }
189
+ /**
190
+ * Create a vote
191
+ */
192
+ async createVote(wishId, fingerprint, voterEmail) {
193
+ return this.post("/api/v1/votes", {
194
+ wish_id: wishId,
195
+ fingerprint,
196
+ voter_email: voterEmail
197
+ });
198
+ }
199
+ /**
200
+ * Delete a vote
201
+ */
202
+ async deleteVote(voteId) {
203
+ return this.delete(`/api/v1/votes/${voteId}`);
204
+ }
205
+ // ============================================================================
206
+ // Comments
207
+ // ============================================================================
208
+ /**
209
+ * Get comments for a wish
210
+ */
211
+ async getComments(wishId, options) {
212
+ const params = {
213
+ wish_id: wishId
214
+ };
215
+ if (options?.page) params.page = String(options.page);
216
+ if (options?.per_page) params.per_page = String(options.per_page);
217
+ const response = await this.get("/api/v1/comments", params);
218
+ if (!response.success) {
219
+ return {
220
+ success: false,
221
+ error: response.error
222
+ };
223
+ }
224
+ const comments = response.data || [];
225
+ return {
226
+ success: true,
227
+ data: {
228
+ data: comments,
229
+ total: comments.length,
230
+ page: options?.page || 1,
231
+ per_page: options?.per_page || 20,
232
+ total_pages: 1
233
+ }
234
+ };
235
+ }
236
+ /**
237
+ * Create a comment
238
+ */
239
+ async createComment(data) {
240
+ return this.post("/api/v1/comments", {
241
+ ...data,
242
+ author_type: "anonymous",
243
+ is_official: false
244
+ });
245
+ }
246
+ // ============================================================================
247
+ // Roadmap
248
+ // ============================================================================
249
+ /**
250
+ * Get roadmap data for the project
251
+ */
252
+ async getRoadmapData() {
253
+ const params = {
254
+ project_id: this.projectId
255
+ };
256
+ if (this.orgSlug && this.projectSlug) {
257
+ params.org_slug = this.orgSlug;
258
+ params.project_slug = this.projectSlug;
259
+ }
260
+ return this.get("/portal/roadmap-data", params);
261
+ }
262
+ // ============================================================================
263
+ // Releases
264
+ // ============================================================================
265
+ /**
266
+ * Get public releases for the project
267
+ */
268
+ async getReleases(options) {
269
+ if (!this.orgSlug || !this.projectSlug) {
270
+ return {
271
+ success: false,
272
+ error: {
273
+ code: "MISSING_SLUGS",
274
+ message: "orgSlug and projectSlug are required for releases endpoint"
275
+ }
276
+ };
277
+ }
278
+ const params = {};
279
+ if (options?.limit) params.limit = String(options.limit);
280
+ return this.get(
281
+ `/api/v1/releases/public/${this.orgSlug}/${this.projectSlug}`,
282
+ params
283
+ );
284
+ }
285
+ /**
286
+ * Get a single release by slug
287
+ */
288
+ async getRelease(releaseSlug) {
289
+ if (!this.orgSlug || !this.projectSlug) {
290
+ return {
291
+ success: false,
292
+ error: {
293
+ code: "MISSING_SLUGS",
294
+ message: "orgSlug and projectSlug are required for releases endpoint"
295
+ }
296
+ };
297
+ }
298
+ return this.get(
299
+ `/api/v1/releases/public/${this.orgSlug}/${this.projectSlug}/${releaseSlug}`
300
+ );
301
+ }
302
+ /**
303
+ * Get features for a release (public endpoint)
304
+ */
305
+ async getReleaseFeatures(releaseSlug) {
306
+ if (!this.orgSlug || !this.projectSlug) {
307
+ return {
308
+ success: false,
309
+ error: {
310
+ code: "MISSING_SLUGS",
311
+ message: "orgSlug and projectSlug are required for release features endpoint"
312
+ }
313
+ };
314
+ }
315
+ return this.get(
316
+ `/api/v1/releases/public/${this.orgSlug}/${this.projectSlug}/${releaseSlug}/features`
317
+ );
318
+ }
319
+ // ============================================================================
320
+ // Help Center
321
+ // ============================================================================
322
+ /**
323
+ * Get help center collection for the project
324
+ */
325
+ async getHelpCollection() {
326
+ return this.get("/portal/help", {
327
+ project_id: this.projectId
328
+ });
329
+ }
330
+ /**
331
+ * Get a help flow by slug
332
+ */
333
+ async getHelpFlow(slug) {
334
+ return this.get(`/portal/help/flows/${slug}`, {
335
+ project_id: this.projectId
336
+ });
337
+ }
338
+ /**
339
+ * Get a help article by slug
340
+ */
341
+ async getHelpArticle(slug, flowId) {
342
+ return this.get(`/portal/help/articles/${slug}`, {
343
+ flow_id: flowId
344
+ });
345
+ }
346
+ // ============================================================================
347
+ // Support
348
+ // ============================================================================
349
+ /**
350
+ * Upload a file via public portal (no auth required)
351
+ */
352
+ async uploadFile(file) {
353
+ const url = `${this.baseUrl}/portal/files/upload`;
354
+ const formData = new FormData();
355
+ formData.append("file", file);
356
+ formData.append("project_id", this.projectId);
357
+ try {
358
+ const response = await fetch(url, {
359
+ method: "POST",
360
+ body: formData
361
+ });
362
+ const data = await response.json();
363
+ if (!response.ok) {
364
+ return {
365
+ success: false,
366
+ error: {
367
+ code: data.error?.code || "UPLOAD_ERROR",
368
+ message: data.error?.message || data.message || "File upload failed"
369
+ }
370
+ };
371
+ }
372
+ return {
373
+ success: true,
374
+ data: data.data || data
375
+ };
376
+ } catch (error) {
377
+ return {
378
+ success: false,
379
+ error: {
380
+ code: "UPLOAD_ERROR",
381
+ message: error instanceof Error ? error.message : "File upload failed"
382
+ }
383
+ };
384
+ }
385
+ }
386
+ /**
387
+ * Submit a support request
388
+ */
389
+ async submitSupportRequest(data) {
390
+ const uploadedAttachments = [];
391
+ if (data.attachments && data.attachments.length > 0) {
392
+ for (const file of data.attachments) {
393
+ if (file.size > 10 * 1024 * 1024) {
394
+ return {
395
+ success: false,
396
+ error: {
397
+ code: "FILE_TOO_LARGE",
398
+ message: `File "${file.name}" is too large. Maximum size is 10MB.`
399
+ }
400
+ };
401
+ }
402
+ const uploadResponse = await this.uploadFile(file);
403
+ if (uploadResponse.success && uploadResponse.data) {
404
+ uploadedAttachments.push({
405
+ url: uploadResponse.data.url,
406
+ name: uploadResponse.data.name,
407
+ size: uploadResponse.data.size,
408
+ mime_type: uploadResponse.data.mime_type
409
+ });
410
+ } else {
411
+ return {
412
+ success: false,
413
+ error: uploadResponse.error || {
414
+ code: "UPLOAD_ERROR",
415
+ message: "Failed to upload attachment"
416
+ }
417
+ };
418
+ }
419
+ }
420
+ }
421
+ const payload = {
422
+ project_id: this.projectId,
423
+ subject: data.subject,
424
+ description: data.description,
425
+ user_email: data.user_email
426
+ };
427
+ if (data.user_name) payload.user_name = data.user_name;
428
+ if (data.category) payload.category = data.category;
429
+ if (uploadedAttachments.length > 0) payload.attachments = uploadedAttachments;
430
+ return this.post("/portal/support-requests", payload);
431
+ }
432
+ /**
433
+ * Request a magic link to access support tickets
434
+ */
435
+ async sendSupportMagicLink(userEmail) {
436
+ return this.post("/portal/support-requests/send-magic-link", {
437
+ project_id: this.projectId,
438
+ user_email: userEmail
439
+ });
440
+ }
441
+ /**
442
+ * Verify magic link token and get user's support tickets
443
+ */
444
+ async verifySupportToken(token) {
445
+ return this.get(
446
+ "/portal/support-requests/verify-token",
447
+ {
448
+ token,
449
+ project_id: this.projectId
450
+ }
451
+ );
452
+ }
453
+ /**
454
+ * Get a specific support ticket using magic link token
455
+ */
456
+ async getSupportTicket(ticketId, token) {
457
+ return this.get(`/portal/support-requests/${ticketId}`, {
458
+ token
459
+ });
460
+ }
461
+ /**
462
+ * Add a message to a support ticket
463
+ */
464
+ async addSupportMessage(ticketId, token, content) {
465
+ const url = `/portal/support-requests/${ticketId}/messages`;
466
+ const fullUrl = `${this.baseUrl}${url}`;
467
+ try {
468
+ const response = await fetch(fullUrl, {
469
+ method: "POST",
470
+ headers: {
471
+ "Content-Type": "application/json",
472
+ "Authorization": `Bearer ${token}`
473
+ },
474
+ body: JSON.stringify({ content })
475
+ });
476
+ const data = await response.json();
477
+ if (!response.ok) {
478
+ return {
479
+ success: false,
480
+ error: {
481
+ code: String(response.status),
482
+ message: data.message || data.error || "An error occurred"
483
+ }
484
+ };
485
+ }
486
+ if (data && typeof data === "object" && "success" in data) {
487
+ return data;
488
+ }
489
+ return {
490
+ success: true,
491
+ data
492
+ };
493
+ } catch (error) {
494
+ return {
495
+ success: false,
496
+ error: {
497
+ code: "NETWORK_ERROR",
498
+ message: error instanceof Error ? error.message : "Network error"
499
+ }
500
+ };
501
+ }
502
+ }
503
+ // ============================================================================
504
+ // Page Data (Combined)
505
+ // ============================================================================
506
+ /**
507
+ * Get all public page data in one request
508
+ */
509
+ async getPageData() {
510
+ const params = {
511
+ project_id: this.projectId
512
+ };
513
+ if (this.orgSlug) params.org_slug = this.orgSlug;
514
+ if (this.projectSlug) params.project_slug = this.projectSlug;
515
+ return this.get("/portal/page-data", params);
516
+ }
517
+ };
518
+ var DEFAULT_API_URL = "https://api.appgram.dev";
519
+ var DEFAULT_LIGHT_COLORS = {
520
+ primary: "#0EA5E9",
521
+ // Arctic blue
522
+ secondary: "#6B7280",
523
+ // Gray
524
+ accent: "#0EA5E9",
525
+ // Arctic blue
526
+ background: "#FFFFFF",
527
+ // White
528
+ text: "#242424",
529
+ // Near-black
530
+ cardBackground: "#F7F7F7",
531
+ cardText: "#242424"
532
+ };
533
+ var DEFAULT_DARK_COLORS = {
534
+ primary: "#38BDF8",
535
+ // Lighter arctic blue
536
+ secondary: "#3A3A3A",
537
+ // Dark gray (subtle for borders)
538
+ accent: "#38BDF8",
539
+ // Lighter arctic blue
540
+ background: "#0A0A0A",
541
+ // Near-black
542
+ text: "#E5E5E5",
543
+ // Light gray
544
+ cardBackground: "#1A1A1A",
545
+ cardText: "#E5E5E5"
546
+ };
547
+ var DEFAULT_THEME = {
548
+ typography: {
549
+ fontFamily: "inherit"
550
+ },
551
+ borderRadius: 8
552
+ };
553
+ function getSystemIsDark() {
554
+ if (typeof window === "undefined") return false;
555
+ return window.matchMedia("(prefers-color-scheme: dark)").matches;
556
+ }
557
+ function resolveIsDark(mode) {
558
+ if (mode === "dark") return true;
559
+ if (mode === "light") return false;
560
+ return getSystemIsDark();
561
+ }
562
+ function AppgramProvider({
563
+ config,
564
+ children
565
+ }) {
566
+ const [fingerprint, setFingerprint] = react.useState(null);
567
+ const themeMode = config.theme?.mode ?? "system";
568
+ const [isDark, setIsDark] = react.useState(() => resolveIsDark(themeMode));
569
+ react.useEffect(() => {
570
+ if (config.enableFingerprinting !== false) {
571
+ setFingerprint(chunk75P634IK_js.getFingerprint());
572
+ }
573
+ }, [config.enableFingerprinting]);
574
+ react.useEffect(() => {
575
+ if (themeMode !== "system" || typeof window === "undefined") {
576
+ setIsDark(resolveIsDark(themeMode));
577
+ return;
578
+ }
579
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
580
+ setIsDark(mediaQuery.matches);
581
+ const handler = (e) => setIsDark(e.matches);
582
+ mediaQuery.addEventListener("change", handler);
583
+ return () => mediaQuery.removeEventListener("change", handler);
584
+ }, [themeMode]);
585
+ const client = react.useMemo(() => {
586
+ return new AppgramClient({
587
+ baseUrl: config.apiUrl || DEFAULT_API_URL,
588
+ projectId: config.projectId,
589
+ orgSlug: config.orgSlug,
590
+ projectSlug: config.projectSlug
591
+ });
592
+ }, [config.apiUrl, config.projectId, config.orgSlug, config.projectSlug]);
593
+ const lightColors = react.useMemo(() => ({
594
+ ...DEFAULT_LIGHT_COLORS,
595
+ ...config.theme?.colors
596
+ }), [config.theme?.colors]);
597
+ const darkColors = react.useMemo(() => ({
598
+ ...DEFAULT_DARK_COLORS,
599
+ ...config.theme?.darkColors
600
+ }), [config.theme?.darkColors]);
601
+ const currentColors = isDark ? darkColors : lightColors;
602
+ const theme = react.useMemo(() => {
603
+ return {
604
+ mode: themeMode,
605
+ colors: lightColors,
606
+ darkColors,
607
+ typography: {
608
+ ...DEFAULT_THEME.typography,
609
+ ...config.theme?.typography
610
+ },
611
+ borderRadius: config.theme?.borderRadius ?? DEFAULT_THEME.borderRadius,
612
+ // Include resolved state for components
613
+ isDark,
614
+ currentColors
615
+ };
616
+ }, [themeMode, lightColors, darkColors, config.theme?.typography, config.theme?.borderRadius, isDark, currentColors]);
617
+ const contextValue = react.useMemo(() => ({
618
+ config: {
619
+ ...config,
620
+ apiUrl: config.apiUrl || DEFAULT_API_URL
621
+ },
622
+ client,
623
+ fingerprint,
624
+ theme
625
+ }), [config, client, fingerprint, theme]);
626
+ react.useEffect(() => {
627
+ if (typeof document === "undefined") return;
628
+ const root = document.documentElement;
629
+ const colors = currentColors;
630
+ root.setAttribute("data-appgram-theme", isDark ? "dark" : "light");
631
+ if (colors.primary) root.style.setProperty("--appgram-primary", colors.primary);
632
+ if (colors.secondary) root.style.setProperty("--appgram-secondary", colors.secondary);
633
+ if (colors.accent) root.style.setProperty("--appgram-accent", colors.accent);
634
+ if (colors.background) root.style.setProperty("--appgram-background", colors.background);
635
+ if (colors.text) root.style.setProperty("--appgram-foreground", colors.text);
636
+ if (colors.cardBackground) root.style.setProperty("--appgram-card", colors.cardBackground);
637
+ if (colors.cardText) root.style.setProperty("--appgram-card-foreground", colors.cardText);
638
+ if (theme.borderRadius) root.style.setProperty("--appgram-radius", `${theme.borderRadius}px`);
639
+ if (theme.typography?.fontFamily) root.style.setProperty("--appgram-font-family", theme.typography.fontFamily);
640
+ }, [currentColors, isDark, theme.borderRadius, theme.typography?.fontFamily]);
641
+ return /* @__PURE__ */ jsxRuntime.jsx(chunk75P634IK_js.AppgramContext.Provider, { value: contextValue, children });
642
+ }
643
+
644
+ Object.defineProperty(exports, "useWish", {
645
+ enumerable: true,
646
+ get: function () { return chunkZJZ3A2S3_js.useWish; }
647
+ });
648
+ Object.defineProperty(exports, "HelpArticleDetail", {
649
+ enumerable: true,
650
+ get: function () { return chunk3UBJGXCO_js.HelpArticleDetail; }
651
+ });
652
+ Object.defineProperty(exports, "HelpArticles", {
653
+ enumerable: true,
654
+ get: function () { return chunk3UBJGXCO_js.HelpArticles; }
655
+ });
656
+ Object.defineProperty(exports, "HelpCenter", {
657
+ enumerable: true,
658
+ get: function () { return chunk3UBJGXCO_js.HelpCenter; }
659
+ });
660
+ Object.defineProperty(exports, "HelpCollections", {
661
+ enumerable: true,
662
+ get: function () { return chunk3UBJGXCO_js.HelpCollections; }
663
+ });
664
+ Object.defineProperty(exports, "ReleaseCard", {
665
+ enumerable: true,
666
+ get: function () { return chunk3UBJGXCO_js.ReleaseCard; }
667
+ });
668
+ Object.defineProperty(exports, "ReleaseDetail", {
669
+ enumerable: true,
670
+ get: function () { return chunk3UBJGXCO_js.ReleaseDetail; }
671
+ });
672
+ Object.defineProperty(exports, "ReleaseList", {
673
+ enumerable: true,
674
+ get: function () { return chunk3UBJGXCO_js.ReleaseList; }
675
+ });
676
+ Object.defineProperty(exports, "Releases", {
677
+ enumerable: true,
678
+ get: function () { return chunk3UBJGXCO_js.Releases; }
679
+ });
680
+ Object.defineProperty(exports, "RoadmapBoard", {
681
+ enumerable: true,
682
+ get: function () { return chunk3UBJGXCO_js.RoadmapBoard; }
683
+ });
684
+ Object.defineProperty(exports, "RoadmapColumn", {
685
+ enumerable: true,
686
+ get: function () { return chunk3UBJGXCO_js.RoadmapColumn; }
687
+ });
688
+ Object.defineProperty(exports, "StatusBoard", {
689
+ enumerable: true,
690
+ get: function () { return chunk3UBJGXCO_js.StatusBoard; }
691
+ });
692
+ Object.defineProperty(exports, "StatusIncidentDetail", {
693
+ enumerable: true,
694
+ get: function () { return chunk3UBJGXCO_js.StatusIncidentDetail; }
695
+ });
696
+ Object.defineProperty(exports, "SubmitWishForm", {
697
+ enumerable: true,
698
+ get: function () { return chunk3UBJGXCO_js.SubmitWishForm; }
699
+ });
700
+ Object.defineProperty(exports, "SupportForm", {
701
+ enumerable: true,
702
+ get: function () { return chunk3UBJGXCO_js.SupportForm; }
703
+ });
704
+ Object.defineProperty(exports, "VoteButton", {
705
+ enumerable: true,
706
+ get: function () { return chunk3UBJGXCO_js.VoteButton; }
707
+ });
708
+ Object.defineProperty(exports, "WhatsNewPopup", {
709
+ enumerable: true,
710
+ get: function () { return chunk3UBJGXCO_js.WhatsNewPopup; }
711
+ });
712
+ Object.defineProperty(exports, "WishCard", {
713
+ enumerable: true,
714
+ get: function () { return chunk3UBJGXCO_js.WishCard; }
715
+ });
716
+ Object.defineProperty(exports, "WishDetail", {
717
+ enumerable: true,
718
+ get: function () { return chunk3UBJGXCO_js.WishDetail; }
719
+ });
720
+ Object.defineProperty(exports, "WishList", {
721
+ enumerable: true,
722
+ get: function () { return chunk3UBJGXCO_js.WishList; }
723
+ });
724
+ Object.defineProperty(exports, "cn", {
725
+ enumerable: true,
726
+ get: function () { return chunk75P634IK_js.cn; }
727
+ });
728
+ Object.defineProperty(exports, "getFingerprint", {
729
+ enumerable: true,
730
+ get: function () { return chunk75P634IK_js.getFingerprint; }
731
+ });
732
+ Object.defineProperty(exports, "resetFingerprint", {
733
+ enumerable: true,
734
+ get: function () { return chunk75P634IK_js.resetFingerprint; }
735
+ });
736
+ Object.defineProperty(exports, "useAppgramContext", {
737
+ enumerable: true,
738
+ get: function () { return chunk75P634IK_js.useAppgramContext; }
739
+ });
740
+ Object.defineProperty(exports, "useComments", {
741
+ enumerable: true,
742
+ get: function () { return chunk75P634IK_js.useComments; }
743
+ });
744
+ Object.defineProperty(exports, "useHelpArticle", {
745
+ enumerable: true,
746
+ get: function () { return chunk75P634IK_js.useHelpArticle; }
747
+ });
748
+ Object.defineProperty(exports, "useHelpCenter", {
749
+ enumerable: true,
750
+ get: function () { return chunk75P634IK_js.useHelpCenter; }
751
+ });
752
+ Object.defineProperty(exports, "useHelpFlow", {
753
+ enumerable: true,
754
+ get: function () { return chunk75P634IK_js.useHelpFlow; }
755
+ });
756
+ Object.defineProperty(exports, "useRelease", {
757
+ enumerable: true,
758
+ get: function () { return chunk75P634IK_js.useRelease; }
759
+ });
760
+ Object.defineProperty(exports, "useReleases", {
761
+ enumerable: true,
762
+ get: function () { return chunk75P634IK_js.useReleases; }
763
+ });
764
+ Object.defineProperty(exports, "useRoadmap", {
765
+ enumerable: true,
766
+ get: function () { return chunk75P634IK_js.useRoadmap; }
767
+ });
768
+ Object.defineProperty(exports, "useSupport", {
769
+ enumerable: true,
770
+ get: function () { return chunk75P634IK_js.useSupport; }
771
+ });
772
+ Object.defineProperty(exports, "useVote", {
773
+ enumerable: true,
774
+ get: function () { return chunk75P634IK_js.useVote; }
775
+ });
776
+ Object.defineProperty(exports, "useWishes", {
777
+ enumerable: true,
778
+ get: function () { return chunk75P634IK_js.useWishes; }
779
+ });
780
+ exports.AppgramClient = AppgramClient;
781
+ exports.AppgramProvider = AppgramProvider;
782
+ //# sourceMappingURL=index.js.map
783
+ //# sourceMappingURL=index.js.map