react-native-insider 7.1.0 → 8.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.
@@ -0,0 +1,290 @@
1
+ import InsiderAppCards from './InsiderAppCards';
2
+ import { resolveWithCallback } from './Util';
3
+
4
+ class InsiderAppCardContent {
5
+ #title;
6
+ #description;
7
+
8
+ constructor({ title, description }) {
9
+ this.#title = title;
10
+ this.#description = description;
11
+ }
12
+
13
+ get title() {
14
+ return this.#title;
15
+ }
16
+
17
+ get description() {
18
+ return this.#description;
19
+ }
20
+ }
21
+
22
+ class InsiderAppCardImage {
23
+ #url;
24
+
25
+ constructor({ url }) {
26
+ this.#url = url;
27
+ }
28
+
29
+ get url() {
30
+ return this.#url;
31
+ }
32
+ }
33
+
34
+ class InsiderAppCardButton {
35
+ #data;
36
+ #buttonId;
37
+ #appCardId;
38
+ #text;
39
+ #action;
40
+
41
+ constructor(appCardId, data) {
42
+ this.#data = data;
43
+ this.#buttonId = data.id;
44
+ this.#appCardId = appCardId;
45
+ this.#text = data.text;
46
+ this.#action = InsiderAppCardAction.fromData(data.action);
47
+ }
48
+
49
+ get buttonId() {
50
+ return this.#buttonId;
51
+ }
52
+
53
+ get appCardId() {
54
+ return this.#appCardId;
55
+ }
56
+
57
+ get text() {
58
+ return this.#text;
59
+ }
60
+
61
+ get action() {
62
+ return this.#action;
63
+ }
64
+
65
+ get data() {
66
+ return this.#data;
67
+ }
68
+
69
+ click() {
70
+ InsiderAppCards.clickButton(this);
71
+ }
72
+ }
73
+
74
+ class InsiderAppCardAction {
75
+ #type;
76
+
77
+ constructor({ type }) {
78
+ this.#type = type;
79
+ }
80
+
81
+ get type() {
82
+ return this.#type;
83
+ }
84
+
85
+ static fromData(data) {
86
+ if (!data) return null;
87
+
88
+ switch (data.type) {
89
+ case 'deep_link':
90
+ return new InsiderAppCardDeeplinkAction(data);
91
+ case 'feedback':
92
+ return new InsiderAppCardFeedbackAction(data);
93
+ case 'open_settings':
94
+ return new InsiderAppCardOpenSettingsAction(data);
95
+ default:
96
+ return null;
97
+ }
98
+ }
99
+
100
+ runAction() {
101
+ throw new Error('runAction() must be implemented by subclasses');
102
+ }
103
+ }
104
+
105
+ class InsiderAppCardDeeplinkAction extends InsiderAppCardAction {
106
+ #urlScheme;
107
+ #internalBrowserUrl;
108
+ #externalBrowserUrl;
109
+ #json;
110
+ #keysAndValues;
111
+
112
+ constructor(data) {
113
+ super({ type: 'deep_link' });
114
+ this.#urlScheme = data.url_scheme;
115
+ this.#internalBrowserUrl = data.internal_browser_url;
116
+ this.#externalBrowserUrl = data.external_browser_url;
117
+ this.#json = data.json;
118
+ this.#keysAndValues = data.key_value;
119
+ }
120
+
121
+ get url() {
122
+ if (this.#urlScheme && this.#urlScheme.length > 0)
123
+ return this.#urlScheme;
124
+ else if (this.#internalBrowserUrl && this.#internalBrowserUrl.length > 0)
125
+ return this.#internalBrowserUrl;
126
+ else if (this.#externalBrowserUrl && this.#externalBrowserUrl.length > 0)
127
+ return this.#externalBrowserUrl;
128
+ else
129
+ return null;
130
+ }
131
+
132
+ get deeplinkType() {
133
+ if (this.#urlScheme && this.#urlScheme.length > 0)
134
+ return 'url_scheme';
135
+ else if (this.#internalBrowserUrl && this.#internalBrowserUrl.length > 0)
136
+ return 'internal';
137
+ else if (this.#externalBrowserUrl && this.#externalBrowserUrl.length > 0)
138
+ return 'external';
139
+ else
140
+ return 'unknown';
141
+ }
142
+
143
+ get json() {
144
+ return this.#json ? JSON.parse(this.#json) : null;
145
+ }
146
+
147
+ get keysAndValues() {
148
+ return this.#keysAndValues;
149
+ }
150
+ }
151
+
152
+ class InsiderAppCardOpenSettingsAction extends InsiderAppCardAction {
153
+ constructor() {
154
+ super({ type: 'open_settings' });
155
+ }
156
+
157
+ }
158
+
159
+ class InsiderAppCardFeedbackAction extends InsiderAppCardAction {
160
+ constructor() {
161
+ super({ type: 'feedback' });
162
+ }
163
+ }
164
+
165
+ class InsiderAppCard {
166
+ #data;
167
+ #appCardId;
168
+ #type;
169
+ #isRead;
170
+ #images;
171
+ #content;
172
+ #buttons;
173
+ #action;
174
+
175
+ constructor(data) {
176
+ this.#data = data;
177
+ this.#appCardId = data.id;
178
+ this.#type = data.type;
179
+ this.#isRead = data.read;
180
+ this.#images = data.images ? data.images.map(x => new InsiderAppCardImage(x)) : null;
181
+ this.#content = data.content ? new InsiderAppCardContent(data.content) : null;
182
+ this.#buttons = data.buttons ? data.buttons.map(x => new InsiderAppCardButton(data.id, x)) : null;
183
+ this.#action = InsiderAppCardAction.fromData(data.action);
184
+ }
185
+
186
+ get appCardId() {
187
+ return this.#appCardId;
188
+ }
189
+
190
+ get type() {
191
+ return this.#type;
192
+ }
193
+
194
+ get isRead() {
195
+ return this.#isRead;
196
+ }
197
+
198
+ get images() {
199
+ return this.#images;
200
+ }
201
+
202
+ get content() {
203
+ return this.#content;
204
+ }
205
+
206
+ get buttons() {
207
+ return this.#buttons;
208
+ }
209
+
210
+ get action() {
211
+ return this.#action;
212
+ }
213
+
214
+ get data() {
215
+ return JSON.parse(JSON.stringify(this.#data));
216
+ }
217
+
218
+ markAsRead(completion) {
219
+ const promise = new Promise((resolve, reject) => {
220
+ InsiderAppCards.markAsRead([this.appCardId], error => {
221
+ if (error) reject(error);
222
+ else {
223
+ this.#isRead = true;
224
+ resolve();
225
+ }
226
+ });
227
+ });
228
+
229
+ return resolveWithCallback(promise, completion);
230
+ }
231
+
232
+ markAsUnread(completion) {
233
+ const promise = new Promise((resolve, reject) => {
234
+ InsiderAppCards.markAsUnread([this.appCardId], error => {
235
+ if (error) reject(error);
236
+ else {
237
+ this.#isRead = false;
238
+ resolve();
239
+ }
240
+ });
241
+ });
242
+
243
+ return resolveWithCallback(promise, completion);
244
+ }
245
+
246
+ delete(completion) {
247
+ const promise = new Promise((resolve, reject) => {
248
+ InsiderAppCards.delete([this.appCardId], error => {
249
+ if (error) reject(error);
250
+ else resolve();
251
+ });
252
+ });
253
+
254
+ return resolveWithCallback(promise, completion);
255
+ }
256
+
257
+ view() {
258
+ InsiderAppCards.view(this);
259
+ }
260
+
261
+ click() {
262
+ InsiderAppCards.click(this);
263
+ }
264
+ }
265
+
266
+ class InsiderAppCardsCampaignResponse {
267
+ #appCards;
268
+
269
+ constructor({ items }) {
270
+ this.#appCards = items?.map(x => new InsiderAppCard(x));
271
+ }
272
+
273
+ get appCards() {
274
+ return this.#appCards;
275
+ }
276
+ }
277
+
278
+ export {
279
+ InsiderAppCardContent,
280
+ InsiderAppCardImage,
281
+ InsiderAppCardButton,
282
+
283
+ InsiderAppCardAction,
284
+ InsiderAppCardDeeplinkAction,
285
+ InsiderAppCardOpenSettingsAction,
286
+ InsiderAppCardFeedbackAction,
287
+
288
+ InsiderAppCard,
289
+ InsiderAppCardsCampaignResponse,
290
+ };
@@ -0,0 +1,268 @@
1
+ import {
2
+ InsiderAppCardsCampaignResponse,
3
+ InsiderAppCard,
4
+ InsiderAppCardButton,
5
+ } from './InsiderAppCard';
6
+
7
+ /**
8
+ * Main API for accessing and managing app cards (campaigns) functionality.
9
+ *
10
+ * This interface provides methods to retrieve app card campaigns and notifications
11
+ * from the Insider platform. App cards can contain text, images, and
12
+ * interactive buttons.
13
+ *
14
+ * The app cards API allows you to:
15
+ * - Fetch app card campaigns with their content and metadata
16
+ * - Access app card read/unread status
17
+ * - Handle interactive buttons within app cards
18
+ * - Support multiple content types (text, images)
19
+ */
20
+ interface InsiderAppCards {
21
+ /**
22
+ * Retrieves the user's app card campaigns.
23
+ *
24
+ * Fetches all available app cards from the Insider platform for the current user.
25
+ * This method cancels any pending campaign requests before initiating a new one.
26
+ *
27
+ * The campaign response contains app cards that may include:
28
+ * - Marketing notifications and promotional content
29
+ * - Multi-media content (text, images)
30
+ * - Interactive buttons with associated actions
31
+ * - Read/unread status for each app card
32
+ *
33
+ * @param completion - A completion handler called when the campaigns are retrieved or an error occurs.
34
+ * The completion handler takes two parameters:
35
+ * - error: An error object if the request fails, undefined otherwise.
36
+ * - campaignResponse: An InsiderAppCardsCampaignResponse containing the user's app cards. Will be undefined if an error occurred.
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * appCards.getCampaigns((error, campaignResponse) => {
41
+ * if (error) {
42
+ * console.log('Failed to fetch campaigns:', error.message);
43
+ * } else {
44
+ * campaignResponse.appCards.forEach(appCard => {
45
+ * console.log('App Card Id:', appCard.appCardId, 'Read:', appCard.isRead);
46
+ * });
47
+ * }
48
+ * });
49
+ * ```
50
+ */
51
+ getCampaigns(completion: (error?: Error, campaignResponse?: InsiderAppCardsCampaignResponse) => void): void;
52
+
53
+ /**
54
+ * Retrieves the user's app card campaigns and returns a promise.
55
+ *
56
+ * Fetches all available app cards from the Insider platform for the current user.
57
+ * This method cancels any pending campaign requests before initiating a new one.
58
+ *
59
+ * @returns A Promise that resolves with the campaign response or rejects with an error.
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * try {
64
+ * const campaignResponse = await appCards.getCampaigns();
65
+ * campaignResponse.appCards.forEach(appCard => {
66
+ * console.log('App Card Id:', appCard.appCardId, 'Read:', appCard.isRead);
67
+ * });
68
+ * } catch (error) {
69
+ * console.log('Failed to fetch campaigns:', error.message);
70
+ * }
71
+ * ```
72
+ */
73
+ getCampaigns(): Promise<InsiderAppCardsCampaignResponse>;
74
+
75
+ /**
76
+ * Marks specified app cards as read.
77
+ *
78
+ * Updates the read status of one or more app cards to indicate they have been viewed by the user.
79
+ * This operation synchronizes with the Insider backend to persist the read state across devices.
80
+ *
81
+ * @param appCardIds - An array of app card identifiers to mark as read. Each Id should correspond to a valid
82
+ * app card Id from the campaigns. Empty arrays are allowed but will result in no operation.
83
+ * @param completion - A completion handler called when the operation finishes.
84
+ * The completion handler takes one parameter:
85
+ * - error: An error object if the request fails, undefined if successful.
86
+ *
87
+ * @example
88
+ * ```typescript
89
+ * appCards.markAsRead(['card_123', 'card_456'], (error) => {
90
+ * if (error) {
91
+ * console.log('Failed to mark app cards as read:', error.message);
92
+ * } else {
93
+ * console.log('App cards marked as read successfully');
94
+ * }
95
+ * });
96
+ * ```
97
+ *
98
+ * @remarks App card Ids that don't exist are silently ignored.
99
+ */
100
+ markAsRead(appCardIds: string[], completion: (error?: Error) => void): void;
101
+
102
+ /**
103
+ * Marks specified app cards as read and returns a promise.
104
+ *
105
+ * Updates the read status of one or more app cards to indicate they have been viewed by the user.
106
+ * This operation synchronizes with the Insider backend to persist the read state across devices.
107
+ *
108
+ * @param appCardIds - An array of app card identifiers to mark as read. Each Id should correspond to a valid
109
+ * app card Id from the campaigns. Empty arrays are allowed but will result in no operation.
110
+ * @returns A Promise that resolves when successful or rejects with an error.
111
+ *
112
+ * @example
113
+ * ```typescript
114
+ * try {
115
+ * await appCards.markAsRead(['card_123', 'card_456']);
116
+ * console.log('App cards marked as read successfully');
117
+ * } catch (error) {
118
+ * console.log('Failed to mark app cards as read:', error.message);
119
+ * }
120
+ * ```
121
+ *
122
+ * @remarks App card Ids that don't exist are silently ignored.
123
+ */
124
+ markAsRead(appCardIds: string[]): Promise<void>;
125
+
126
+ /**
127
+ * Marks specified app cards as unread.
128
+ *
129
+ * Updates the read status of one or more app cards to indicate they are unread.
130
+ * This operation synchronizes with the Insider backend to persist the unread state across devices.
131
+ *
132
+ * @param appCardIds - An array of app card identifiers to mark as unread. Each Id should correspond to a valid
133
+ * app card Id from the campaigns. Empty arrays are allowed but will result in no operation.
134
+ * @param completion - A completion handler called when the operation finishes.
135
+ * The completion handler takes one parameter:
136
+ * - error: An error object if the request fails, undefined if successful.
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * appCards.markAsUnread(['card_123', 'card_456'], (error) => {
141
+ * if (error) {
142
+ * console.log('Failed to mark app cards as unread:', error.message);
143
+ * } else {
144
+ * console.log('App cards marked as unread successfully');
145
+ * }
146
+ * });
147
+ * ```
148
+ *
149
+ * @remarks App card Ids that don't exist are silently ignored.
150
+ */
151
+ markAsUnread(appCardIds: string[], completion: (error?: Error) => void): void;
152
+
153
+ /**
154
+ * Marks specified app cards as unread and returns a promise.
155
+ *
156
+ * Updates the read status of one or more app cards to indicate they are unread.
157
+ * This operation synchronizes with the Insider backend to persist the unread state across devices.
158
+ *
159
+ * @param appCardIds - An array of app card identifiers to mark as unread. Each Id should correspond to a valid
160
+ * app card Id from the campaigns. Empty arrays are allowed but will result in no operation.
161
+ * @returns A Promise that resolves when successful or rejects with an error.
162
+ *
163
+ * @example
164
+ * ```typescript
165
+ * try {
166
+ * await appCards.markAsUnread(['card_123', 'card_456']);
167
+ * console.log('App cards marked as unread successfully');
168
+ * } catch (error) {
169
+ * console.log('Failed to mark app cards as unread:', error.message);
170
+ * }
171
+ * ```
172
+ *
173
+ * @remarks App card Ids that don't exist are silently ignored.
174
+ */
175
+ markAsUnread(appCardIds: string[]): Promise<void>;
176
+
177
+ /**
178
+ * Deletes specified app cards.
179
+ *
180
+ * Permanently removes one or more app cards from the user's campaigns.
181
+ * This operation synchronizes with the Insider backend.
182
+ *
183
+ * @param appCardIds - An array of app card identifiers to delete.
184
+ * @param completion - A completion handler called when the operation finishes.
185
+ *
186
+ * @example
187
+ * ```typescript
188
+ * appCards.delete(['card_123', 'card_456'], (error) => {
189
+ * if (error) {
190
+ * console.log('Failed to delete app cards:', error.message);
191
+ * } else {
192
+ * console.log('App cards deleted successfully');
193
+ * }
194
+ * });
195
+ * ```
196
+ */
197
+ delete(appCardIds: string[], completion: (error?: Error) => void): void;
198
+
199
+ /**
200
+ * Deletes specified app cards and returns a promise.
201
+ *
202
+ * Permanently removes one or more app cards from the user's campaigns.
203
+ * This operation synchronizes with the Insider backend.
204
+ *
205
+ * @param appCardIds - An array of app card identifiers to delete.
206
+ * @returns A Promise that resolves when successful or rejects with an error.
207
+ *
208
+ * @example
209
+ * ```typescript
210
+ * try {
211
+ * await appCards.delete(['card_123', 'card_456']);
212
+ * console.log('App cards deleted successfully');
213
+ * } catch (error) {
214
+ * console.log('Failed to delete app cards:', error.message);
215
+ * }
216
+ * ```
217
+ */
218
+ delete(appCardIds: string[]): Promise<void>;
219
+
220
+ /**
221
+ * Records a view event for an app card.
222
+ *
223
+ * Call this method when a user views an app card.
224
+ * This notifies observers and can be used for analytics tracking.
225
+ *
226
+ * @param appCard - The app card that was viewed.
227
+ *
228
+ * @example
229
+ * ```typescript
230
+ * appCards.view(appCard);
231
+ * ```
232
+ */
233
+ view(appCard: InsiderAppCard): void;
234
+
235
+ /**
236
+ * Records a click event for an app card.
237
+ *
238
+ * Call this method when a user clicks or taps on an app card.
239
+ * This executes the app card's deeplink action (if present) and notifies observers.
240
+ *
241
+ * @param appCard - The app card that was clicked.
242
+ *
243
+ * @example
244
+ * ```typescript
245
+ * appCards.click(appCard);
246
+ * ```
247
+ */
248
+ click(appCard: InsiderAppCard): void;
249
+
250
+ /**
251
+ * Records a click event for a button within an app card.
252
+ *
253
+ * Call this method when a user clicks or taps on a button in an app card.
254
+ * This executes the button's action (if present) and notifies observers.
255
+ *
256
+ * @param button - The button that was clicked.
257
+ *
258
+ * @example
259
+ * ```typescript
260
+ * appCards.clickButton(button);
261
+ * ```
262
+ */
263
+ clickButton(button: InsiderAppCardButton): void;
264
+ }
265
+
266
+ declare const InsiderAppCards: InsiderAppCards;
267
+
268
+ export default InsiderAppCards;
@@ -0,0 +1,98 @@
1
+ import { NativeModules } from 'react-native';
2
+ import { resolveWithCallback } from './Util';
3
+ import { InsiderAppCardsCampaignResponse, InsiderAppCardButton, InsiderAppCard } from './InsiderAppCard';
4
+ import { InsiderAppCardsError, InsiderAppCardsErrorCode } from './InsiderAppCardsError';
5
+
6
+ const Insider = NativeModules.RNInsider;
7
+
8
+ const InsiderAppCards = Object.freeze({
9
+ getCampaigns(completion) {
10
+ const promise = new Promise((resolve, reject) => {
11
+ Insider.getAppCardsCampaigns((error, result) => {
12
+ if (error) reject(InsiderAppCardsError.from(error));
13
+ else resolve(new InsiderAppCardsCampaignResponse(result));
14
+ });
15
+ });
16
+
17
+ return resolveWithCallback(promise, completion);
18
+ },
19
+ markAsRead(appCardIds, completion) {
20
+ const promise = new Promise((resolve, reject) => {
21
+ if (
22
+ !Array.isArray(appCardIds) ||
23
+ appCardIds.length === 0 ||
24
+ appCardIds.some(id => typeof id !== 'string')
25
+ ) {
26
+ reject(new InsiderAppCardsError(InsiderAppCardsErrorCode.INVALID_PARAMETER, 'appCardIds must be a non-empty array of strings.'));
27
+ return;
28
+ }
29
+
30
+ Insider.markAppCardsAsRead(appCardIds, (error) => {
31
+ if (error) reject(InsiderAppCardsError.from(error));
32
+ else resolve();
33
+ });
34
+ });
35
+
36
+ return resolveWithCallback(promise, completion);
37
+ },
38
+ markAsUnread(appCardIds, completion) {
39
+ const promise = new Promise((resolve, reject) => {
40
+ if (
41
+ !Array.isArray(appCardIds) ||
42
+ appCardIds.length === 0 ||
43
+ appCardIds.some(id => typeof id !== 'string')
44
+ ) {
45
+ reject(new InsiderAppCardsError(InsiderAppCardsErrorCode.INVALID_PARAMETER, 'appCardIds must be a non-empty array of strings.'));
46
+ return;
47
+ }
48
+
49
+ Insider.markAppCardsAsUnread(appCardIds, (error) => {
50
+ if (error) reject(InsiderAppCardsError.from(error));
51
+ else resolve();
52
+ });
53
+ });
54
+
55
+ return resolveWithCallback(promise, completion);
56
+ },
57
+ delete(appCardIds, completion) {
58
+ const promise = new Promise((resolve, reject) => {
59
+ if (
60
+ !Array.isArray(appCardIds) ||
61
+ appCardIds.length === 0 ||
62
+ appCardIds.some(id => typeof id !== 'string')
63
+ ) {
64
+ reject(new InsiderAppCardsError(InsiderAppCardsErrorCode.INVALID_PARAMETER, 'appCardIds must be a non-empty array of strings.'));
65
+ return;
66
+ }
67
+
68
+ Insider.deleteAppCards(appCardIds, (error) => {
69
+ if (error) reject(InsiderAppCardsError.from(error));
70
+ else resolve();
71
+ });
72
+ });
73
+
74
+ return resolveWithCallback(promise, completion);
75
+ },
76
+ view(appCard) {
77
+ if (!(appCard instanceof InsiderAppCard)) {
78
+ throw new InsiderAppCardsError(InsiderAppCardsErrorCode.INVALID_PARAMETER, `appCard must be of type InsiderAppCard, received: ${typeof appCard}`);
79
+ }
80
+
81
+ Insider.viewAppCard(appCard.data);
82
+ },
83
+ click(appCard) {
84
+ if (!(appCard instanceof InsiderAppCard)) {
85
+ throw new InsiderAppCardsError(InsiderAppCardsErrorCode.INVALID_PARAMETER, `appCard must be of type InsiderAppCard, received: ${typeof appCard}`);
86
+ }
87
+
88
+ Insider.clickAppCard(appCard.data);
89
+ },
90
+ clickButton(button) {
91
+ if (!(button instanceof InsiderAppCardButton)) {
92
+ throw new InsiderAppCardsError(InsiderAppCardsErrorCode.INVALID_PARAMETER, `button must be of type InsiderAppCardButton, received: ${typeof button}`);
93
+ }
94
+ Insider.clickAppCardButton(button.appCardId, button.data);
95
+ },
96
+ });
97
+
98
+ export default InsiderAppCards;