@loyalytics/swan-react-native-sdk 2.1.3-beta.3 → 2.1.3
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/lib/commonjs/version.js +1 -1
- package/lib/commonjs/version.js.map +1 -1
- package/lib/module/version.js +1 -1
- package/lib/module/version.js.map +1 -1
- package/lib/typescript/commonjs/src/version.d.ts +1 -1
- package/lib/typescript/commonjs/src/version.d.ts.map +1 -1
- package/lib/typescript/module/src/version.d.ts +1 -1
- package/lib/typescript/module/src/version.d.ts.map +1 -1
- package/package.json +4 -2
- package/android/src/test/kotlin/com/loyalytics/swan/templates/carousel/CarouselTemplateTest.kt +0 -125
- package/scripts/test-carousel-push.js +0 -266
package/lib/commonjs/version.js
CHANGED
|
@@ -8,5 +8,5 @@ exports.SDK_VERSION = void 0;
|
|
|
8
8
|
// This file is generated from package.json version during build.
|
|
9
9
|
// See scripts/generate-version.js
|
|
10
10
|
|
|
11
|
-
const SDK_VERSION = exports.SDK_VERSION = '2.1.3
|
|
11
|
+
const SDK_VERSION = exports.SDK_VERSION = '2.1.3';
|
|
12
12
|
//# sourceMappingURL=version.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["SDK_VERSION","exports"],"sourceRoot":"../../src","sources":["version.ts"],"mappings":";;;;;;AAAA;AACA;AACA;;AAEO,MAAMA,WAAW,GAAAC,OAAA,CAAAD,WAAA,GAAG,
|
|
1
|
+
{"version":3,"names":["SDK_VERSION","exports"],"sourceRoot":"../../src","sources":["version.ts"],"mappings":";;;;;;AAAA;AACA;AACA;;AAEO,MAAMA,WAAW,GAAAC,OAAA,CAAAD,WAAA,GAAG,OAAO","ignoreList":[]}
|
package/lib/module/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["SDK_VERSION"],"sourceRoot":"../../src","sources":["version.ts"],"mappings":";;AAAA;AACA;AACA;;AAEA,OAAO,MAAMA,WAAW,GAAG,
|
|
1
|
+
{"version":3,"names":["SDK_VERSION"],"sourceRoot":"../../src","sources":["version.ts"],"mappings":";;AAAA;AACA;AACA;;AAEA,OAAO,MAAMA,WAAW,GAAG,OAAO","ignoreList":[]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "2.1.3
|
|
1
|
+
export declare const SDK_VERSION = "2.1.3";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../../src/version.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../../src/version.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,UAAU,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "2.1.3
|
|
1
|
+
export declare const SDK_VERSION = "2.1.3";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../../src/version.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../../src/version.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,UAAU,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loyalytics/swan-react-native-sdk",
|
|
3
|
-
"version": "2.1.3
|
|
3
|
+
"version": "2.1.3",
|
|
4
4
|
"description": "React Native SDK for Swan",
|
|
5
5
|
"source": "./src/index.tsx",
|
|
6
6
|
"main": "./lib/commonjs/index.js",
|
|
@@ -34,7 +34,9 @@
|
|
|
34
34
|
"!**/__tests__",
|
|
35
35
|
"!**/__fixtures__",
|
|
36
36
|
"!**/__mocks__",
|
|
37
|
-
"!**/.*"
|
|
37
|
+
"!**/.*",
|
|
38
|
+
"!android/src/test",
|
|
39
|
+
"!scripts/test-carousel-push.js"
|
|
38
40
|
],
|
|
39
41
|
"scripts": {
|
|
40
42
|
"test": "jest",
|
package/android/src/test/kotlin/com/loyalytics/swan/templates/carousel/CarouselTemplateTest.kt
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
package com.loyalytics.swan.templates.carousel
|
|
2
|
-
|
|
3
|
-
import org.junit.Assert.*
|
|
4
|
-
import org.junit.Test
|
|
5
|
-
|
|
6
|
-
class CarouselTemplateTest {
|
|
7
|
-
|
|
8
|
-
// --- wrapIndex ---
|
|
9
|
-
|
|
10
|
-
@Test
|
|
11
|
-
fun `wrapIndex forward at end wraps to first`() {
|
|
12
|
-
assertEquals(0, wrapIndex(3, 3))
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
@Test
|
|
16
|
-
fun `wrapIndex backward at start wraps to last`() {
|
|
17
|
-
assertEquals(2, wrapIndex(-1, 3))
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
@Test
|
|
21
|
-
fun `wrapIndex normal forward`() {
|
|
22
|
-
assertEquals(1, wrapIndex(1, 3))
|
|
23
|
-
assertEquals(2, wrapIndex(2, 3))
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
@Test
|
|
27
|
-
fun `wrapIndex normal backward`() {
|
|
28
|
-
assertEquals(1, wrapIndex(1, 3))
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
@Test
|
|
32
|
-
fun `wrapIndex with single item always returns 0`() {
|
|
33
|
-
assertEquals(0, wrapIndex(0, 1))
|
|
34
|
-
assertEquals(0, wrapIndex(1, 1))
|
|
35
|
-
assertEquals(0, wrapIndex(-1, 1))
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
@Test
|
|
39
|
-
fun `wrapIndex with size 0 returns 0`() {
|
|
40
|
-
assertEquals(0, wrapIndex(0, 0))
|
|
41
|
-
assertEquals(0, wrapIndex(5, 0))
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
@Test
|
|
45
|
-
fun `wrapIndex large negative wraps correctly`() {
|
|
46
|
-
// -5 with size 3: -5 mod 3 = -2, + 3 = 1
|
|
47
|
-
assertEquals(1, wrapIndex(-5, 3))
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
@Test
|
|
51
|
-
fun `wrapIndex large positive wraps correctly`() {
|
|
52
|
-
// 7 with size 3: 7 mod 3 = 1
|
|
53
|
-
assertEquals(1, wrapIndex(7, 3))
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
@Test
|
|
57
|
-
fun `wrapIndex full cycle returns to start`() {
|
|
58
|
-
// Going forward through all items returns to 0
|
|
59
|
-
val size = 5
|
|
60
|
-
for (i in 0 until size) {
|
|
61
|
-
assertEquals(i, wrapIndex(i, size))
|
|
62
|
-
}
|
|
63
|
-
assertEquals(0, wrapIndex(size, size))
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
@Test
|
|
67
|
-
fun `wrapIndex two items alternates correctly`() {
|
|
68
|
-
assertEquals(0, wrapIndex(0, 2))
|
|
69
|
-
assertEquals(1, wrapIndex(1, 2))
|
|
70
|
-
assertEquals(0, wrapIndex(2, 2))
|
|
71
|
-
assertEquals(1, wrapIndex(-1, 2))
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
@Test
|
|
75
|
-
fun `wrapIndex filmstrip prev-current-next for 3 items`() {
|
|
76
|
-
val size = 3
|
|
77
|
-
// At index 0: prev=2, current=0, next=1
|
|
78
|
-
assertEquals(2, wrapIndex(0 - 1, size))
|
|
79
|
-
assertEquals(0, wrapIndex(0, size))
|
|
80
|
-
assertEquals(1, wrapIndex(0 + 1, size))
|
|
81
|
-
|
|
82
|
-
// At index 2: prev=1, current=2, next=0
|
|
83
|
-
assertEquals(1, wrapIndex(2 - 1, size))
|
|
84
|
-
assertEquals(2, wrapIndex(2, size))
|
|
85
|
-
assertEquals(0, wrapIndex(2 + 1, size))
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// --- canHandle ---
|
|
89
|
-
|
|
90
|
-
@Test
|
|
91
|
-
fun `canHandle returns true for carousel type`() {
|
|
92
|
-
val template = CarouselTemplate()
|
|
93
|
-
assertTrue(template.canHandle("carousel"))
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
@Test
|
|
97
|
-
fun `canHandle returns false for other types`() {
|
|
98
|
-
val template = CarouselTemplate()
|
|
99
|
-
assertFalse(template.canHandle("timer"))
|
|
100
|
-
assertFalse(template.canHandle("cta"))
|
|
101
|
-
assertFalse(template.canHandle(""))
|
|
102
|
-
assertFalse(template.canHandle("CAROUSEL"))
|
|
103
|
-
assertFalse(template.canHandle("Carousel"))
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// --- CarouselAutoRemoteViews.MAX_FLIPPER_IMAGES cap ---
|
|
107
|
-
// (Cannot directly test private const, but we verify the build method
|
|
108
|
-
// is accessible and the type is correct)
|
|
109
|
-
|
|
110
|
-
@Test
|
|
111
|
-
fun `CarouselAutoRemoteViews is a singleton object`() {
|
|
112
|
-
// Verify the object exists and is accessible
|
|
113
|
-
assertNotNull(CarouselAutoRemoteViews)
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
@Test
|
|
117
|
-
fun `CarouselFilmstripRemoteViews is a singleton object`() {
|
|
118
|
-
assertNotNull(CarouselFilmstripRemoteViews)
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
@Test
|
|
122
|
-
fun `CarouselRemoteViews is a singleton object`() {
|
|
123
|
-
assertNotNull(CarouselRemoteViews)
|
|
124
|
-
}
|
|
125
|
-
}
|
|
@@ -1,266 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Swan SDK - Carousel Push Notification Test Script
|
|
5
|
-
*
|
|
6
|
-
* Sends test carousel push notifications via Firebase Admin SDK.
|
|
7
|
-
* Requires firebase-admin to be installed (already in devDependencies).
|
|
8
|
-
*
|
|
9
|
-
* Usage:
|
|
10
|
-
* node scripts/test-carousel-push.js --token <FCM_TOKEN> [--mode manual|auto] [--scenario <name>]
|
|
11
|
-
*
|
|
12
|
-
* Environment:
|
|
13
|
-
* GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account-key.json
|
|
14
|
-
*
|
|
15
|
-
* Scenarios:
|
|
16
|
-
* manual-3 — Manual carousel with 3 products (default)
|
|
17
|
-
* auto-5 — Auto carousel with 5 products, 2s interval (ViewFlipper)
|
|
18
|
-
* filmstrip-4 — Filmstrip variant with 4 products (3-image preview strip)
|
|
19
|
-
* single-item — Single item carousel (should hide arrows)
|
|
20
|
-
* invalid-json — Invalid carouselItems JSON (tests fallback)
|
|
21
|
-
* no-images — Items without imageUrl (tests filtering)
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
const admin = require('firebase-admin');
|
|
25
|
-
|
|
26
|
-
// Parse CLI args
|
|
27
|
-
const args = process.argv.slice(2);
|
|
28
|
-
const getArg = (name) => {
|
|
29
|
-
const idx = args.indexOf(`--${name}`);
|
|
30
|
-
return idx !== -1 ? args[idx + 1] : undefined;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const fcmToken = getArg('token');
|
|
34
|
-
const mode = getArg('mode') || 'manual';
|
|
35
|
-
const scenarioName = getArg('scenario') || 'manual-3';
|
|
36
|
-
|
|
37
|
-
if (!fcmToken) {
|
|
38
|
-
console.error(
|
|
39
|
-
'Usage: node scripts/test-carousel-push.js --token <FCM_TOKEN> [--mode manual|auto] [--scenario <name>]'
|
|
40
|
-
);
|
|
41
|
-
console.error(
|
|
42
|
-
'\nAvailable scenarios: manual-3, auto-5, filmstrip-4, single-item, invalid-json, no-images'
|
|
43
|
-
);
|
|
44
|
-
process.exit(1);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Initialize Firebase Admin
|
|
48
|
-
if (!admin.apps.length) {
|
|
49
|
-
admin.initializeApp({
|
|
50
|
-
credential: admin.credential.applicationDefault(),
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const SAMPLE_IMAGES = [
|
|
55
|
-
'https://picsum.photos/seed/swan1/400/200',
|
|
56
|
-
'https://picsum.photos/seed/swan2/400/200',
|
|
57
|
-
'https://picsum.photos/seed/swan3/400/200',
|
|
58
|
-
'https://picsum.photos/seed/swan4/400/200',
|
|
59
|
-
'https://picsum.photos/seed/swan5/400/200',
|
|
60
|
-
];
|
|
61
|
-
|
|
62
|
-
const scenarios = {
|
|
63
|
-
'manual-3': {
|
|
64
|
-
name: 'Manual carousel — 3 products',
|
|
65
|
-
data: {
|
|
66
|
-
notificationType: 'carousel',
|
|
67
|
-
carouselMode: 'manual',
|
|
68
|
-
title: 'Flash Sale - Top Picks!',
|
|
69
|
-
body: 'Swipe to see our best deals',
|
|
70
|
-
channelId: 'swan_promotional',
|
|
71
|
-
carouselItems: JSON.stringify([
|
|
72
|
-
{
|
|
73
|
-
imageUrl: SAMPLE_IMAGES[0],
|
|
74
|
-
title: 'Wireless Earbuds',
|
|
75
|
-
body: '50% off - $29.99',
|
|
76
|
-
route: '/product/101',
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
imageUrl: SAMPLE_IMAGES[1],
|
|
80
|
-
title: 'Smart Watch',
|
|
81
|
-
body: 'New arrival',
|
|
82
|
-
route: '/product/102',
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
imageUrl: SAMPLE_IMAGES[2],
|
|
86
|
-
title: 'Phone Case',
|
|
87
|
-
body: 'Best seller',
|
|
88
|
-
route: '/product/103',
|
|
89
|
-
},
|
|
90
|
-
]),
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
'auto-5': {
|
|
94
|
-
name: 'Auto carousel — 5 products, 2s interval (ViewFlipper)',
|
|
95
|
-
data: {
|
|
96
|
-
notificationType: 'carousel',
|
|
97
|
-
carouselMode: 'auto',
|
|
98
|
-
carouselInterval: '2000',
|
|
99
|
-
title: 'Recommended for You',
|
|
100
|
-
body: 'Based on your recent browsing',
|
|
101
|
-
channelId: 'swan_general',
|
|
102
|
-
defaultRoute: '/recommended',
|
|
103
|
-
carouselItems: JSON.stringify([
|
|
104
|
-
{
|
|
105
|
-
imageUrl: SAMPLE_IMAGES[0],
|
|
106
|
-
title: 'Product A',
|
|
107
|
-
body: '$19.99',
|
|
108
|
-
route: '/product/201',
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
imageUrl: SAMPLE_IMAGES[1],
|
|
112
|
-
title: 'Product B',
|
|
113
|
-
body: '$24.99',
|
|
114
|
-
route: '/product/202',
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
imageUrl: SAMPLE_IMAGES[2],
|
|
118
|
-
title: 'Product C',
|
|
119
|
-
body: '$14.99',
|
|
120
|
-
route: '/product/203',
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
imageUrl: SAMPLE_IMAGES[3],
|
|
124
|
-
title: 'Product D',
|
|
125
|
-
body: '$39.99',
|
|
126
|
-
route: '/product/204',
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
imageUrl: SAMPLE_IMAGES[4],
|
|
130
|
-
title: 'Product E',
|
|
131
|
-
body: '$9.99',
|
|
132
|
-
route: '/product/205',
|
|
133
|
-
},
|
|
134
|
-
]),
|
|
135
|
-
},
|
|
136
|
-
},
|
|
137
|
-
'filmstrip-4': {
|
|
138
|
-
name: 'Filmstrip carousel — 4 products with side previews',
|
|
139
|
-
data: {
|
|
140
|
-
notificationType: 'carousel',
|
|
141
|
-
carouselMode: 'manual',
|
|
142
|
-
carouselVariant: 'filmstrip',
|
|
143
|
-
title: 'Summer Collection',
|
|
144
|
-
body: 'Tap the side images to browse',
|
|
145
|
-
channelId: 'swan_promotional',
|
|
146
|
-
carouselItems: JSON.stringify([
|
|
147
|
-
{
|
|
148
|
-
imageUrl: SAMPLE_IMAGES[0],
|
|
149
|
-
title: 'Summer Dress',
|
|
150
|
-
body: '$49.99',
|
|
151
|
-
route: '/product/401',
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
imageUrl: SAMPLE_IMAGES[1],
|
|
155
|
-
title: 'Beach Sandals',
|
|
156
|
-
body: '$29.99',
|
|
157
|
-
route: '/product/402',
|
|
158
|
-
},
|
|
159
|
-
{
|
|
160
|
-
imageUrl: SAMPLE_IMAGES[2],
|
|
161
|
-
title: 'Sun Hat',
|
|
162
|
-
body: '$19.99',
|
|
163
|
-
route: '/product/403',
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
imageUrl: SAMPLE_IMAGES[3],
|
|
167
|
-
title: 'Sunglasses',
|
|
168
|
-
body: '$34.99',
|
|
169
|
-
route: '/product/404',
|
|
170
|
-
},
|
|
171
|
-
]),
|
|
172
|
-
},
|
|
173
|
-
},
|
|
174
|
-
'single-item': {
|
|
175
|
-
name: 'Single item carousel (should look like normal image notification)',
|
|
176
|
-
data: {
|
|
177
|
-
notificationType: 'carousel',
|
|
178
|
-
carouselMode: 'manual',
|
|
179
|
-
title: 'Just for You',
|
|
180
|
-
body: 'Check this out',
|
|
181
|
-
channelId: 'swan_promotional',
|
|
182
|
-
carouselItems: JSON.stringify([
|
|
183
|
-
{
|
|
184
|
-
imageUrl: SAMPLE_IMAGES[0],
|
|
185
|
-
title: 'Featured Product',
|
|
186
|
-
body: 'Limited time offer',
|
|
187
|
-
route: '/product/301',
|
|
188
|
-
},
|
|
189
|
-
]),
|
|
190
|
-
},
|
|
191
|
-
},
|
|
192
|
-
'invalid-json': {
|
|
193
|
-
name: 'Invalid carouselItems JSON (should fall back to standard notification)',
|
|
194
|
-
data: {
|
|
195
|
-
notificationType: 'carousel',
|
|
196
|
-
carouselMode: 'manual',
|
|
197
|
-
title: 'Bad Payload Test',
|
|
198
|
-
body: 'Should show as standard notification',
|
|
199
|
-
channelId: 'swan_general',
|
|
200
|
-
carouselItems: 'this is not valid json {{{',
|
|
201
|
-
},
|
|
202
|
-
},
|
|
203
|
-
'no-images': {
|
|
204
|
-
name: 'Items without imageUrl (should filter and fall back)',
|
|
205
|
-
data: {
|
|
206
|
-
notificationType: 'carousel',
|
|
207
|
-
carouselMode: 'manual',
|
|
208
|
-
title: 'No Images Test',
|
|
209
|
-
body: 'Items lack imageUrl',
|
|
210
|
-
channelId: 'swan_general',
|
|
211
|
-
carouselItems: JSON.stringify([
|
|
212
|
-
{ title: 'No image 1', body: 'Missing imageUrl' },
|
|
213
|
-
{ title: 'No image 2', body: 'Also missing' },
|
|
214
|
-
]),
|
|
215
|
-
},
|
|
216
|
-
},
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
async function sendPush(scenario) {
|
|
220
|
-
console.log(`\nSending: ${scenario.name}`);
|
|
221
|
-
console.log(`Mode: ${scenario.data.carouselMode || 'manual'}`);
|
|
222
|
-
console.log(`Token: ${fcmToken.substring(0, 20)}...`);
|
|
223
|
-
|
|
224
|
-
const message = {
|
|
225
|
-
token: fcmToken,
|
|
226
|
-
data: scenario.data,
|
|
227
|
-
android: {
|
|
228
|
-
priority: 'high',
|
|
229
|
-
},
|
|
230
|
-
apns: {
|
|
231
|
-
payload: {
|
|
232
|
-
aps: {
|
|
233
|
-
'mutable-content': 1,
|
|
234
|
-
'category': 'swan_carousel',
|
|
235
|
-
},
|
|
236
|
-
},
|
|
237
|
-
},
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
try {
|
|
241
|
-
const response = await admin.messaging().send(message);
|
|
242
|
-
console.log(`Sent successfully! messageId: ${response}`);
|
|
243
|
-
return response;
|
|
244
|
-
} catch (error) {
|
|
245
|
-
console.error(`Failed to send: ${error.message}`);
|
|
246
|
-
return null;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
async function main() {
|
|
251
|
-
const scenario = scenarios[scenarioName];
|
|
252
|
-
if (!scenario) {
|
|
253
|
-
console.error(`Unknown scenario: ${scenarioName}`);
|
|
254
|
-
console.error(`Available: ${Object.keys(scenarios).join(', ')}`);
|
|
255
|
-
process.exit(1);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// Override mode if --mode flag is provided and scenario supports it
|
|
259
|
-
if (mode && scenario.data.carouselMode !== undefined) {
|
|
260
|
-
scenario.data.carouselMode = mode;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
await sendPush(scenario);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
main().catch(console.error);
|