@buoy-gg/notifications 7.0.41 → 7.0.42
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/components/LocalNotificationTest.js +1 -185
- package/lib/commonjs/components/NotificationTestView.js +1 -329
- package/lib/commonjs/components/NotificationToolView.js +1 -673
- package/lib/commonjs/components/notificationStyles.js +1 -292
- package/lib/commonjs/expo.js +1 -247
- package/lib/commonjs/index.js +1 -148
- package/lib/commonjs/json.js +1 -58
- package/lib/commonjs/payload.js +1 -68
- package/lib/commonjs/preset.js +1 -56
- package/lib/commonjs/preview.js +1 -18
- package/lib/commonjs/recorder.js +1 -339
- package/lib/commonjs/runtime.js +1 -110
- package/lib/commonjs/storage.js +1 -61
- package/lib/commonjs/types.js +0 -1
- package/lib/module/components/LocalNotificationTest.js +1 -180
- package/lib/module/components/NotificationTestView.js +1 -324
- package/lib/module/components/NotificationToolView.js +1 -668
- package/lib/module/components/notificationStyles.js +1 -288
- package/lib/module/expo.js +1 -241
- package/lib/module/index.js +1 -13
- package/lib/module/json.js +1 -51
- package/lib/module/payload.js +1 -63
- package/lib/module/preset.js +1 -50
- package/lib/module/preview.js +1 -14
- package/lib/module/recorder.js +1 -332
- package/lib/module/runtime.js +1 -103
- package/lib/module/storage.js +1 -56
- package/lib/module/types.js +0 -1
- package/package.json +2 -2
- package/lib/commonjs/components/LocalNotificationTest.js.map +0 -1
- package/lib/commonjs/components/NotificationTestView.js.map +0 -1
- package/lib/commonjs/components/NotificationToolView.js.map +0 -1
- package/lib/commonjs/components/notificationStyles.js.map +0 -1
- package/lib/commonjs/expo.js.map +0 -1
- package/lib/commonjs/index.js.map +0 -1
- package/lib/commonjs/json.js.map +0 -1
- package/lib/commonjs/payload.js.map +0 -1
- package/lib/commonjs/preset.js.map +0 -1
- package/lib/commonjs/preview.js.map +0 -1
- package/lib/commonjs/recorder.js.map +0 -1
- package/lib/commonjs/runtime.js.map +0 -1
- package/lib/commonjs/storage.js.map +0 -1
- package/lib/commonjs/types.js.map +0 -1
- package/lib/module/components/LocalNotificationTest.js.map +0 -1
- package/lib/module/components/NotificationTestView.js.map +0 -1
- package/lib/module/components/NotificationToolView.js.map +0 -1
- package/lib/module/components/notificationStyles.js.map +0 -1
- package/lib/module/expo.js.map +0 -1
- package/lib/module/index.js.map +0 -1
- package/lib/module/json.js.map +0 -1
- package/lib/module/payload.js.map +0 -1
- package/lib/module/preset.js.map +0 -1
- package/lib/module/preview.js.map +0 -1
- package/lib/module/recorder.js.map +0 -1
- package/lib/module/runtime.js.map +0 -1
- package/lib/module/storage.js.map +0 -1
- package/lib/module/types.js.map +0 -1
- package/lib/typescript/components/LocalNotificationTest.d.ts.map +0 -1
- package/lib/typescript/components/NotificationTestView.d.ts.map +0 -1
- package/lib/typescript/components/NotificationToolView.d.ts.map +0 -1
- package/lib/typescript/components/notificationStyles.d.ts.map +0 -1
- package/lib/typescript/expo.d.ts.map +0 -1
- package/lib/typescript/index.d.ts.map +0 -1
- package/lib/typescript/json.d.ts.map +0 -1
- package/lib/typescript/payload.d.ts.map +0 -1
- package/lib/typescript/preset.d.ts.map +0 -1
- package/lib/typescript/preview.d.ts.map +0 -1
- package/lib/typescript/recorder.d.ts.map +0 -1
- package/lib/typescript/runtime.d.ts.map +0 -1
- package/lib/typescript/storage.d.ts.map +0 -1
- package/lib/typescript/types.d.ts.map +0 -1
|
@@ -1,288 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { StyleSheet } from "react-native";
|
|
4
|
-
import { monoFont, night } from "@buoy-gg/shared-ui";
|
|
5
|
-
export const styles = StyleSheet.create({
|
|
6
|
-
root: {
|
|
7
|
-
flex: 1,
|
|
8
|
-
minHeight: 0,
|
|
9
|
-
backgroundColor: "transparent"
|
|
10
|
-
},
|
|
11
|
-
fill: {
|
|
12
|
-
flex: 1,
|
|
13
|
-
minHeight: 0
|
|
14
|
-
},
|
|
15
|
-
inlineHeader: {
|
|
16
|
-
paddingHorizontal: 12,
|
|
17
|
-
paddingVertical: 8,
|
|
18
|
-
borderBottomWidth: 1,
|
|
19
|
-
borderBottomColor: night.color.separator
|
|
20
|
-
},
|
|
21
|
-
status: {
|
|
22
|
-
flexDirection: "row",
|
|
23
|
-
alignItems: "center",
|
|
24
|
-
flexWrap: "wrap",
|
|
25
|
-
gap: 12,
|
|
26
|
-
paddingHorizontal: 16,
|
|
27
|
-
paddingVertical: 9
|
|
28
|
-
},
|
|
29
|
-
statusLabel: {
|
|
30
|
-
flexDirection: "row",
|
|
31
|
-
alignItems: "center",
|
|
32
|
-
gap: 6
|
|
33
|
-
},
|
|
34
|
-
dot: {
|
|
35
|
-
width: 5,
|
|
36
|
-
height: 5,
|
|
37
|
-
borderRadius: 3,
|
|
38
|
-
backgroundColor: night.color.textTertiary
|
|
39
|
-
},
|
|
40
|
-
liveDot: {
|
|
41
|
-
backgroundColor: night.color.accent
|
|
42
|
-
},
|
|
43
|
-
caption: {
|
|
44
|
-
color: night.color.textSecondary,
|
|
45
|
-
fontSize: 12,
|
|
46
|
-
lineHeight: 17
|
|
47
|
-
},
|
|
48
|
-
provider: {
|
|
49
|
-
color: night.color.textSecondary,
|
|
50
|
-
fontSize: 11,
|
|
51
|
-
marginLeft: "auto",
|
|
52
|
-
fontFamily: monoFont
|
|
53
|
-
},
|
|
54
|
-
content: {
|
|
55
|
-
padding: 14,
|
|
56
|
-
gap: 20
|
|
57
|
-
},
|
|
58
|
-
eventList: {
|
|
59
|
-
paddingHorizontal: 12,
|
|
60
|
-
paddingTop: 2
|
|
61
|
-
},
|
|
62
|
-
searchRow: {
|
|
63
|
-
flexDirection: "row",
|
|
64
|
-
gap: 8,
|
|
65
|
-
paddingHorizontal: 12,
|
|
66
|
-
paddingBottom: 10,
|
|
67
|
-
alignItems: "center"
|
|
68
|
-
},
|
|
69
|
-
searchField: {
|
|
70
|
-
flex: 1,
|
|
71
|
-
minWidth: 0,
|
|
72
|
-
height: 36,
|
|
73
|
-
flexDirection: "row",
|
|
74
|
-
alignItems: "center",
|
|
75
|
-
gap: 8,
|
|
76
|
-
paddingHorizontal: 10,
|
|
77
|
-
backgroundColor: night.color.glass,
|
|
78
|
-
borderWidth: 1,
|
|
79
|
-
borderColor: night.color.glassBorder,
|
|
80
|
-
borderRadius: night.radius.row
|
|
81
|
-
},
|
|
82
|
-
searchInput: {
|
|
83
|
-
flex: 1,
|
|
84
|
-
minWidth: 0,
|
|
85
|
-
height: "100%",
|
|
86
|
-
color: night.color.text,
|
|
87
|
-
fontSize: 13,
|
|
88
|
-
padding: 0
|
|
89
|
-
},
|
|
90
|
-
clearSearch: {
|
|
91
|
-
padding: 6
|
|
92
|
-
},
|
|
93
|
-
iconButton: {
|
|
94
|
-
width: 34,
|
|
95
|
-
height: 34,
|
|
96
|
-
alignItems: "center",
|
|
97
|
-
justifyContent: "center",
|
|
98
|
-
backgroundColor: night.color.buttonSurface,
|
|
99
|
-
borderRadius: 8,
|
|
100
|
-
borderWidth: 1,
|
|
101
|
-
borderColor: night.color.border
|
|
102
|
-
},
|
|
103
|
-
event: {
|
|
104
|
-
backgroundColor: night.color.glass,
|
|
105
|
-
borderRadius: night.radius.input,
|
|
106
|
-
borderWidth: 1,
|
|
107
|
-
borderColor: night.color.glassBorder,
|
|
108
|
-
paddingHorizontal: 12,
|
|
109
|
-
paddingVertical: 10,
|
|
110
|
-
marginBottom: 6,
|
|
111
|
-
gap: 6
|
|
112
|
-
},
|
|
113
|
-
eventTop: {
|
|
114
|
-
flexDirection: "row",
|
|
115
|
-
alignItems: "center",
|
|
116
|
-
gap: 10,
|
|
117
|
-
justifyContent: "space-between"
|
|
118
|
-
},
|
|
119
|
-
eventKind: {
|
|
120
|
-
flexDirection: "row",
|
|
121
|
-
alignItems: "center",
|
|
122
|
-
gap: 6,
|
|
123
|
-
flex: 1,
|
|
124
|
-
minWidth: 0
|
|
125
|
-
},
|
|
126
|
-
eventLabel: {
|
|
127
|
-
flexShrink: 1,
|
|
128
|
-
fontSize: 11,
|
|
129
|
-
fontWeight: "600"
|
|
130
|
-
},
|
|
131
|
-
timestamp: {
|
|
132
|
-
color: night.color.textSecondary,
|
|
133
|
-
fontFamily: monoFont,
|
|
134
|
-
fontSize: 10
|
|
135
|
-
},
|
|
136
|
-
eventSubject: {
|
|
137
|
-
flexDirection: "row",
|
|
138
|
-
alignItems: "center",
|
|
139
|
-
gap: 8
|
|
140
|
-
},
|
|
141
|
-
eventTitle: {
|
|
142
|
-
flex: 1,
|
|
143
|
-
color: night.color.text,
|
|
144
|
-
fontSize: 15,
|
|
145
|
-
fontWeight: "500"
|
|
146
|
-
},
|
|
147
|
-
eventMeta: {
|
|
148
|
-
color: night.color.textSecondary,
|
|
149
|
-
fontFamily: monoFont,
|
|
150
|
-
fontSize: 10,
|
|
151
|
-
lineHeight: 15
|
|
152
|
-
},
|
|
153
|
-
resultCount: {
|
|
154
|
-
color: night.color.textSecondary,
|
|
155
|
-
fontSize: 12,
|
|
156
|
-
marginBottom: 10,
|
|
157
|
-
marginLeft: 4
|
|
158
|
-
},
|
|
159
|
-
actionRow: {
|
|
160
|
-
flexDirection: "row",
|
|
161
|
-
alignItems: "center",
|
|
162
|
-
flexWrap: "wrap",
|
|
163
|
-
gap: 8
|
|
164
|
-
},
|
|
165
|
-
button: {
|
|
166
|
-
flexDirection: "row",
|
|
167
|
-
alignItems: "center",
|
|
168
|
-
justifyContent: "center",
|
|
169
|
-
gap: 6,
|
|
170
|
-
minHeight: 34,
|
|
171
|
-
paddingVertical: 8,
|
|
172
|
-
paddingHorizontal: 14,
|
|
173
|
-
borderRadius: night.radius.pill,
|
|
174
|
-
backgroundColor: night.color.fillSecondary,
|
|
175
|
-
alignSelf: "flex-start"
|
|
176
|
-
},
|
|
177
|
-
buttonText: {
|
|
178
|
-
color: night.color.accent,
|
|
179
|
-
fontSize: 13,
|
|
180
|
-
fontWeight: "600"
|
|
181
|
-
},
|
|
182
|
-
primaryButton: {
|
|
183
|
-
backgroundColor: night.color.accent
|
|
184
|
-
},
|
|
185
|
-
primaryButtonText: {
|
|
186
|
-
color: night.color.onAccent
|
|
187
|
-
},
|
|
188
|
-
pressed: {
|
|
189
|
-
opacity: 0.7
|
|
190
|
-
},
|
|
191
|
-
disabled: {
|
|
192
|
-
opacity: 0.4
|
|
193
|
-
},
|
|
194
|
-
detailTitle: {
|
|
195
|
-
color: night.color.text,
|
|
196
|
-
fontSize: 20,
|
|
197
|
-
fontWeight: "600"
|
|
198
|
-
},
|
|
199
|
-
field: {
|
|
200
|
-
flexDirection: "row",
|
|
201
|
-
paddingHorizontal: 16,
|
|
202
|
-
paddingVertical: 12,
|
|
203
|
-
gap: 14
|
|
204
|
-
},
|
|
205
|
-
fieldLabel: {
|
|
206
|
-
width: 110,
|
|
207
|
-
flexShrink: 0
|
|
208
|
-
},
|
|
209
|
-
value: {
|
|
210
|
-
flex: 1,
|
|
211
|
-
minWidth: 0,
|
|
212
|
-
color: night.color.text,
|
|
213
|
-
fontFamily: monoFont,
|
|
214
|
-
fontSize: 12,
|
|
215
|
-
lineHeight: 18
|
|
216
|
-
},
|
|
217
|
-
disclosure: {
|
|
218
|
-
flexDirection: "row",
|
|
219
|
-
alignItems: "center",
|
|
220
|
-
justifyContent: "space-between",
|
|
221
|
-
paddingHorizontal: 16,
|
|
222
|
-
paddingVertical: 14
|
|
223
|
-
},
|
|
224
|
-
disclosureTitle: {
|
|
225
|
-
color: night.color.text,
|
|
226
|
-
fontSize: 13,
|
|
227
|
-
fontWeight: "500"
|
|
228
|
-
},
|
|
229
|
-
jsonBody: {
|
|
230
|
-
padding: 10,
|
|
231
|
-
borderTopWidth: 1,
|
|
232
|
-
borderTopColor: night.color.separator
|
|
233
|
-
},
|
|
234
|
-
token: {
|
|
235
|
-
color: night.color.text,
|
|
236
|
-
fontFamily: monoFont,
|
|
237
|
-
fontSize: 12,
|
|
238
|
-
lineHeight: 20
|
|
239
|
-
},
|
|
240
|
-
bodyText: {
|
|
241
|
-
color: night.color.text,
|
|
242
|
-
fontSize: 14,
|
|
243
|
-
lineHeight: 21
|
|
244
|
-
},
|
|
245
|
-
footnote: {
|
|
246
|
-
color: night.color.textSecondary,
|
|
247
|
-
fontSize: 12,
|
|
248
|
-
lineHeight: 18,
|
|
249
|
-
marginTop: 8,
|
|
250
|
-
marginHorizontal: 4
|
|
251
|
-
},
|
|
252
|
-
emptyFootnote: {
|
|
253
|
-
color: night.color.textSecondary,
|
|
254
|
-
fontSize: 12,
|
|
255
|
-
lineHeight: 18,
|
|
256
|
-
textAlign: "center",
|
|
257
|
-
marginHorizontal: 28
|
|
258
|
-
},
|
|
259
|
-
sectionActions: {
|
|
260
|
-
flexDirection: "row",
|
|
261
|
-
marginBottom: 10
|
|
262
|
-
},
|
|
263
|
-
warning: {
|
|
264
|
-
color: night.color.warning,
|
|
265
|
-
fontSize: 12,
|
|
266
|
-
lineHeight: 18
|
|
267
|
-
},
|
|
268
|
-
notice: {
|
|
269
|
-
color: night.color.accent,
|
|
270
|
-
backgroundColor: night.color.glass,
|
|
271
|
-
paddingHorizontal: 16,
|
|
272
|
-
paddingVertical: 10,
|
|
273
|
-
fontSize: 12,
|
|
274
|
-
lineHeight: 18
|
|
275
|
-
},
|
|
276
|
-
errorNotice: {
|
|
277
|
-
color: night.color.danger,
|
|
278
|
-
backgroundColor: night.color.glass,
|
|
279
|
-
paddingHorizontal: 16,
|
|
280
|
-
paddingVertical: 10,
|
|
281
|
-
fontSize: 12,
|
|
282
|
-
lineHeight: 18
|
|
283
|
-
},
|
|
284
|
-
errorText: {
|
|
285
|
-
color: night.color.danger
|
|
286
|
-
}
|
|
287
|
-
});
|
|
288
|
-
//# sourceMappingURL=notificationStyles.js.map
|
|
1
|
+
"use strict";import{StyleSheet as t}from"react-native";import{monoFont as e,night as o}from"@buoy-gg/shared-ui";export const styles=t.create({root:{flex:1,minHeight:0,backgroundColor:"transparent"},fill:{flex:1,minHeight:0},inlineHeader:{paddingHorizontal:12,paddingVertical:8,borderBottomWidth:1,borderBottomColor:o.color.separator},status:{flexDirection:"row",alignItems:"center",flexWrap:"wrap",gap:12,paddingHorizontal:16,paddingVertical:9},statusLabel:{flexDirection:"row",alignItems:"center",gap:6},dot:{width:5,height:5,borderRadius:3,backgroundColor:o.color.textTertiary},liveDot:{backgroundColor:o.color.accent},caption:{color:o.color.textSecondary,fontSize:12,lineHeight:17},provider:{color:o.color.textSecondary,fontSize:11,marginLeft:"auto",fontFamily:e},content:{padding:14,gap:20},eventList:{paddingHorizontal:12,paddingTop:2},searchRow:{flexDirection:"row",gap:8,paddingHorizontal:12,paddingBottom:10,alignItems:"center"},searchField:{flex:1,minWidth:0,height:36,flexDirection:"row",alignItems:"center",gap:8,paddingHorizontal:10,backgroundColor:o.color.glass,borderWidth:1,borderColor:o.color.glassBorder,borderRadius:o.radius.row},searchInput:{flex:1,minWidth:0,height:"100%",color:o.color.text,fontSize:13,padding:0},clearSearch:{padding:6},iconButton:{width:34,height:34,alignItems:"center",justifyContent:"center",backgroundColor:o.color.buttonSurface,borderRadius:8,borderWidth:1,borderColor:o.color.border},event:{backgroundColor:o.color.glass,borderRadius:o.radius.input,borderWidth:1,borderColor:o.color.glassBorder,paddingHorizontal:12,paddingVertical:10,marginBottom:6,gap:6},eventTop:{flexDirection:"row",alignItems:"center",gap:10,justifyContent:"space-between"},eventKind:{flexDirection:"row",alignItems:"center",gap:6,flex:1,minWidth:0},eventLabel:{flexShrink:1,fontSize:11,fontWeight:"600"},timestamp:{color:o.color.textSecondary,fontFamily:e,fontSize:10},eventSubject:{flexDirection:"row",alignItems:"center",gap:8},eventTitle:{flex:1,color:o.color.text,fontSize:15,fontWeight:"500"},eventMeta:{color:o.color.textSecondary,fontFamily:e,fontSize:10,lineHeight:15},resultCount:{color:o.color.textSecondary,fontSize:12,marginBottom:10,marginLeft:4},actionRow:{flexDirection:"row",alignItems:"center",flexWrap:"wrap",gap:8},button:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:6,minHeight:34,paddingVertical:8,paddingHorizontal:14,borderRadius:o.radius.pill,backgroundColor:o.color.fillSecondary,alignSelf:"flex-start"},buttonText:{color:o.color.accent,fontSize:13,fontWeight:"600"},primaryButton:{backgroundColor:o.color.accent},primaryButtonText:{color:o.color.onAccent},pressed:{opacity:.7},disabled:{opacity:.4},detailTitle:{color:o.color.text,fontSize:20,fontWeight:"600"},field:{flexDirection:"row",paddingHorizontal:16,paddingVertical:12,gap:14},fieldLabel:{width:110,flexShrink:0},value:{flex:1,minWidth:0,color:o.color.text,fontFamily:e,fontSize:12,lineHeight:18},disclosure:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingHorizontal:16,paddingVertical:14},disclosureTitle:{color:o.color.text,fontSize:13,fontWeight:"500"},jsonBody:{padding:10,borderTopWidth:1,borderTopColor:o.color.separator},token:{color:o.color.text,fontFamily:e,fontSize:12,lineHeight:20},bodyText:{color:o.color.text,fontSize:14,lineHeight:21},footnote:{color:o.color.textSecondary,fontSize:12,lineHeight:18,marginTop:8,marginHorizontal:4},emptyFootnote:{color:o.color.textSecondary,fontSize:12,lineHeight:18,textAlign:"center",marginHorizontal:28},sectionActions:{flexDirection:"row",marginBottom:10},warning:{color:o.color.warning,fontSize:12,lineHeight:18},notice:{color:o.color.accent,backgroundColor:o.color.glass,paddingHorizontal:16,paddingVertical:10,fontSize:12,lineHeight:18},errorNotice:{color:o.color.danger,backgroundColor:o.color.glass,paddingHorizontal:16,paddingVertical:10,fontSize:12,lineHeight:18},errorText:{color:o.color.danger}});
|
package/lib/module/expo.js
CHANGED
|
@@ -1,241 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { normalizePreviewAppearance } from "./preview";
|
|
4
|
-
import { expoMetadata, responseKey } from "./recorder";
|
|
5
|
-
import { object, string } from "./json";
|
|
6
|
-
|
|
7
|
-
// Structural interfaces let the app pass its installed SDK without a native dependency.
|
|
8
|
-
|
|
9
|
-
function timeout(promise, ms = 15000) {
|
|
10
|
-
return new Promise((resolve, reject) => {
|
|
11
|
-
const timer = setTimeout(() => reject(new Error("Notification SDK timed out. Check permission and network settings, then retry.")), ms);
|
|
12
|
-
promise.then(value => {
|
|
13
|
-
clearTimeout(timer);
|
|
14
|
-
resolve(value);
|
|
15
|
-
}, error => {
|
|
16
|
-
clearTimeout(timer);
|
|
17
|
-
reject(error);
|
|
18
|
-
});
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/** Does not replace presentation, routing or background handlers. */
|
|
23
|
-
export function attachExpoNotifications(recorder, sdk, options) {
|
|
24
|
-
const capabilities = ["received", "responses", "permissions", "device-token"];
|
|
25
|
-
if (sdk.getLastNotificationResponse || sdk.getLastNotificationResponseAsync) capabilities.push("startup-response");
|
|
26
|
-
if (sdk.getPresentedNotificationsAsync) capabilities.push("presented");
|
|
27
|
-
if (sdk.scheduleNotificationAsync) capabilities.push("local-scheduling");
|
|
28
|
-
if (options.projectId && sdk.getExpoPushTokenAsync) capabilities.push("expo-token");
|
|
29
|
-
recorder.configure({
|
|
30
|
-
preview: normalizePreviewAppearance(options.preview),
|
|
31
|
-
provider: "expo",
|
|
32
|
-
platform: options.platform,
|
|
33
|
-
appId: options.appId ?? null,
|
|
34
|
-
providerVersion: options.providerVersion ?? null,
|
|
35
|
-
capabilities
|
|
36
|
-
});
|
|
37
|
-
let disposed = false;
|
|
38
|
-
const subscriptions = [];
|
|
39
|
-
const response = (value, startup = false) => {
|
|
40
|
-
if (disposed || !value) return;
|
|
41
|
-
void recorder.record(startup ? "startup-response" : "response", value, {
|
|
42
|
-
...expoMetadata(value),
|
|
43
|
-
dedupeKey: responseKey(value)
|
|
44
|
-
});
|
|
45
|
-
};
|
|
46
|
-
try {
|
|
47
|
-
subscriptions.push(sdk.addNotificationReceivedListener(value => {
|
|
48
|
-
if (!disposed) void recorder.record("received", value, expoMetadata(value));
|
|
49
|
-
}));
|
|
50
|
-
subscriptions.push(sdk.addNotificationResponseReceivedListener(value => response(value)));
|
|
51
|
-
subscriptions.push(sdk.addPushTokenListener(token => {
|
|
52
|
-
// Token acquisition here can trigger this listener recursively.
|
|
53
|
-
if (!disposed && (token.type === "ios" || token.type === "android")) void recorder.observeToken(token.type === "ios" ? "apns" : "fcm", token.data).catch(() => {});
|
|
54
|
-
}));
|
|
55
|
-
} catch (error) {
|
|
56
|
-
for (const subscription of subscriptions) subscription.remove();
|
|
57
|
-
throw error;
|
|
58
|
-
}
|
|
59
|
-
const initial = Promise.resolve().then(() => sdk.getLastNotificationResponse?.() ?? sdk.getLastNotificationResponseAsync?.()).then(value => response(value, true));
|
|
60
|
-
void initial.catch(() => {});
|
|
61
|
-
const actions = {
|
|
62
|
-
async getPermissions() {
|
|
63
|
-
const permissions = await timeout(sdk.getPermissionsAsync());
|
|
64
|
-
recorder.setPermissions(permissions);
|
|
65
|
-
return recorder.getSnapshot().permissions;
|
|
66
|
-
},
|
|
67
|
-
async listPresented() {
|
|
68
|
-
if (!sdk.getPresentedNotificationsAsync) throw new Error("This notification SDK cannot list presented notifications.");
|
|
69
|
-
const presented = await timeout(sdk.getPresentedNotificationsAsync());
|
|
70
|
-
recorder.setPresented(presented);
|
|
71
|
-
return recorder.getSnapshot().presented;
|
|
72
|
-
},
|
|
73
|
-
async refreshToken(params) {
|
|
74
|
-
const {
|
|
75
|
-
type
|
|
76
|
-
} = object(params);
|
|
77
|
-
if (type === "expo") {
|
|
78
|
-
if (!sdk.getExpoPushTokenAsync || !options.projectId) throw new Error("Set projectId in installExpoNotificationCapture before requesting an Expo token.");
|
|
79
|
-
const token = await timeout(sdk.getExpoPushTokenAsync({
|
|
80
|
-
projectId: options.projectId
|
|
81
|
-
}));
|
|
82
|
-
await recorder.observeToken("expo", token.data, {
|
|
83
|
-
projectId: options.projectId
|
|
84
|
-
});
|
|
85
|
-
return {
|
|
86
|
-
type: "expo",
|
|
87
|
-
value: token.data
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
if (type !== "device") throw new Error('Token type must be "device" or "expo".');
|
|
91
|
-
if (!sdk.getDevicePushTokenAsync) throw new Error("This notification SDK cannot register a device token.");
|
|
92
|
-
const token = await timeout(sdk.getDevicePushTokenAsync());
|
|
93
|
-
if (token.type !== "ios" && token.type !== "android") throw new Error("This platform does not provide an APNs or FCM token.");
|
|
94
|
-
await recorder.observeToken(token.type === "ios" ? "apns" : "fcm", token.data);
|
|
95
|
-
return {
|
|
96
|
-
type: token.type === "ios" ? "apns" : "fcm",
|
|
97
|
-
value: token.data
|
|
98
|
-
};
|
|
99
|
-
},
|
|
100
|
-
async scheduleLocal(params) {
|
|
101
|
-
if (!sdk.scheduleNotificationAsync) throw new Error("This notification SDK cannot schedule local notifications.");
|
|
102
|
-
const {
|
|
103
|
-
title,
|
|
104
|
-
body,
|
|
105
|
-
data,
|
|
106
|
-
seconds
|
|
107
|
-
} = object(params);
|
|
108
|
-
if (typeof title !== "string" || typeof body !== "string" || typeof seconds !== "number" || !Number.isFinite(seconds) || seconds < 1 || seconds > 3600) throw new Error("Provide title, body and a delay from 1 to 3600 seconds.");
|
|
109
|
-
if (data !== undefined && (data === null || typeof data !== "object" || Array.isArray(data))) throw new Error("Local notification data must be an object.");
|
|
110
|
-
const id = await timeout(sdk.scheduleNotificationAsync({
|
|
111
|
-
content: {
|
|
112
|
-
title,
|
|
113
|
-
body,
|
|
114
|
-
data: data ?? {}
|
|
115
|
-
},
|
|
116
|
-
trigger: {
|
|
117
|
-
type: "timeInterval",
|
|
118
|
-
seconds,
|
|
119
|
-
repeats: false
|
|
120
|
-
}
|
|
121
|
-
}));
|
|
122
|
-
await recorder.record("local-scheduled", {
|
|
123
|
-
title,
|
|
124
|
-
body,
|
|
125
|
-
data,
|
|
126
|
-
seconds
|
|
127
|
-
}, {
|
|
128
|
-
notificationId: id,
|
|
129
|
-
title,
|
|
130
|
-
testId: typeof object(data).__buoyTestId === "string" ? object(data).__buoyTestId : null
|
|
131
|
-
});
|
|
132
|
-
return {
|
|
133
|
-
notificationId: id,
|
|
134
|
-
transport: "local"
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
void actions.getPermissions().catch(() => {});
|
|
139
|
-
return {
|
|
140
|
-
actions,
|
|
141
|
-
ready: initial,
|
|
142
|
-
dispose() {
|
|
143
|
-
disposed = true;
|
|
144
|
-
for (const subscription of subscriptions) subscription.remove();
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/** Wrap the handler the app already passes to Notifications.setNotificationHandler. */
|
|
150
|
-
export function instrumentExpoNotificationHandler(recorder, handler) {
|
|
151
|
-
const metadataById = new Map();
|
|
152
|
-
return {
|
|
153
|
-
...handler,
|
|
154
|
-
handleNotification: async function (...args) {
|
|
155
|
-
const metadata = expoMetadata(args[0]);
|
|
156
|
-
if (metadata.notificationId) metadataById.set(metadata.notificationId, metadata);
|
|
157
|
-
if (metadataById.size > 50) metadataById.delete(metadataById.keys().next().value);
|
|
158
|
-
try {
|
|
159
|
-
const behavior = await handler.handleNotification.apply(this, args);
|
|
160
|
-
void recorder.record("presentation-decision", {
|
|
161
|
-
notification: args[0],
|
|
162
|
-
behavior
|
|
163
|
-
}, expoMetadata(args[0]));
|
|
164
|
-
return behavior;
|
|
165
|
-
} catch (error) {
|
|
166
|
-
void recorder.record("presentation-error", {
|
|
167
|
-
notification: args[0],
|
|
168
|
-
error
|
|
169
|
-
}, expoMetadata(args[0]));
|
|
170
|
-
throw error;
|
|
171
|
-
}
|
|
172
|
-
},
|
|
173
|
-
handleError: function (...args) {
|
|
174
|
-
const identifier = string(args[0]);
|
|
175
|
-
const metadata = identifier ? metadataById.get(identifier) : undefined;
|
|
176
|
-
if (identifier) metadataById.delete(identifier);
|
|
177
|
-
void recorder.record("presentation-error", {
|
|
178
|
-
source: "sdk",
|
|
179
|
-
identifier,
|
|
180
|
-
error: args[1]
|
|
181
|
-
}, metadata ?? {
|
|
182
|
-
notificationId: identifier
|
|
183
|
-
});
|
|
184
|
-
return handler.handleError?.apply(this, args);
|
|
185
|
-
}
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/** Expo's background task payload differs from its foreground Notification object. */
|
|
190
|
-
export function expoBackgroundMetadata(value) {
|
|
191
|
-
const metadata = expoMetadata(value);
|
|
192
|
-
const raw = object(value);
|
|
193
|
-
const data = object(raw.data);
|
|
194
|
-
const launchPayload = object(data.UIApplicationLaunchOptionsRemoteNotificationKey);
|
|
195
|
-
let parsed = {};
|
|
196
|
-
if (typeof data.dataString === "string") {
|
|
197
|
-
try {
|
|
198
|
-
parsed = object(JSON.parse(data.dataString));
|
|
199
|
-
} catch {/* Keep malformed data visible in the raw record. */}
|
|
200
|
-
}
|
|
201
|
-
const custom = object(data.body ?? raw.body ?? launchPayload.body);
|
|
202
|
-
return {
|
|
203
|
-
...metadata,
|
|
204
|
-
testId: metadata.testId ?? string(parsed.__buoyTestId) ?? string(custom.__buoyTestId),
|
|
205
|
-
title: metadata.title ?? string(object(raw.notification).title) ?? string(object(object(raw.aps ?? launchPayload.aps).alert).title)
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/** Await local capture for at most 250 ms without extending the task for a desktop connection. */
|
|
210
|
-
async function persistBounded(promise) {
|
|
211
|
-
let timer;
|
|
212
|
-
await Promise.race([promise.catch(() => {}), new Promise(resolve => {
|
|
213
|
-
timer = setTimeout(resolve, 250);
|
|
214
|
-
})]);
|
|
215
|
-
if (timer) clearTimeout(timer);
|
|
216
|
-
}
|
|
217
|
-
export function instrumentNotificationBackgroundTask(recorder, task) {
|
|
218
|
-
recorder.configure({
|
|
219
|
-
capabilities: [...new Set([...recorder.getSnapshot().capabilities, "background-task"])]
|
|
220
|
-
});
|
|
221
|
-
return async function (...args) {
|
|
222
|
-
const value = object(args[0]).data ?? args[0];
|
|
223
|
-
const metadata = expoBackgroundMetadata(value);
|
|
224
|
-
await persistBounded(recorder.record("background-started", args[0], metadata));
|
|
225
|
-
try {
|
|
226
|
-
const result = await task.apply(this, args);
|
|
227
|
-
await persistBounded(recorder.record("background-completed", {
|
|
228
|
-
input: args[0],
|
|
229
|
-
result
|
|
230
|
-
}, metadata));
|
|
231
|
-
return result;
|
|
232
|
-
} catch (error) {
|
|
233
|
-
await persistBounded(recorder.record("background-error", {
|
|
234
|
-
input: args[0],
|
|
235
|
-
error
|
|
236
|
-
}, metadata));
|
|
237
|
-
throw error;
|
|
238
|
-
}
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
//# sourceMappingURL=expo.js.map
|
|
1
|
+
"use strict";import{normalizePreviewAppearance as g}from"./preview";import{expoMetadata as u,responseKey as T}from"./recorder";import{object as r,string as l}from"./json";function y(o,t=15e3){return new Promise((e,n)=>{const s=setTimeout(()=>n(new Error("Notification SDK timed out. Check permission and network settings, then retry.")),t);o.then(a=>{clearTimeout(s);e(a)},a=>{clearTimeout(s);n(a)})})}export function attachExpoNotifications(o,t,e){const n=["received","responses","permissions","device-token"];if(t.getLastNotificationResponse||t.getLastNotificationResponseAsync)n.push("startup-response");if(t.getPresentedNotificationsAsync)n.push("presented");if(t.scheduleNotificationAsync)n.push("local-scheduling");if(e.projectId&&t.getExpoPushTokenAsync)n.push("expo-token");o.configure({preview:g(e.preview),provider:"expo",platform:e.platform,appId:e.appId??null,providerVersion:e.providerVersion??null,capabilities:n});let s=false;const a=[];const h=(i,c=false)=>{if(s||!i)return;void o.record(c?"startup-response":"response",i,{...u(i),dedupeKey:T(i)})};try{a.push(t.addNotificationReceivedListener(i=>{if(!s)void o.record("received",i,u(i))}));a.push(t.addNotificationResponseReceivedListener(i=>h(i)));a.push(t.addPushTokenListener(i=>{if(!s&&(i.type==="ios"||i.type==="android"))void o.observeToken(i.type==="ios"?"apns":"fcm",i.data).catch(()=>{})}))}catch(i){for(const c of a)c.remove();throw i}const w=Promise.resolve().then(()=>t.getLastNotificationResponse?.()??t.getLastNotificationResponseAsync?.()).then(i=>h(i,true));void w.catch(()=>{});const v={async getPermissions(){const i=await y(t.getPermissionsAsync());o.setPermissions(i);return o.getSnapshot().permissions},async listPresented(){if(!t.getPresentedNotificationsAsync)throw new Error("This notification SDK cannot list presented notifications.");const i=await y(t.getPresentedNotificationsAsync());o.setPresented(i);return o.getSnapshot().presented},async refreshToken(i){const{type:c}=r(i);if(c==="expo"){if(!t.getExpoPushTokenAsync||!e.projectId)throw new Error("Set projectId in installExpoNotificationCapture before requesting an Expo token.");const p=await y(t.getExpoPushTokenAsync({projectId:e.projectId}));await o.observeToken("expo",p.data,{projectId:e.projectId});return{type:"expo",value:p.data}}if(c!=="device")throw new Error('Token type must be "device" or "expo".');if(!t.getDevicePushTokenAsync)throw new Error("This notification SDK cannot register a device token.");const d=await y(t.getDevicePushTokenAsync());if(d.type!=="ios"&&d.type!=="android")throw new Error("This platform does not provide an APNs or FCM token.");await o.observeToken(d.type==="ios"?"apns":"fcm",d.data);return{type:d.type==="ios"?"apns":"fcm",value:d.data}},async scheduleLocal(i){if(!t.scheduleNotificationAsync)throw new Error("This notification SDK cannot schedule local notifications.");const{title:c,body:d,data:p,seconds:f}=r(i);if(typeof c!=="string"||typeof d!=="string"||typeof f!=="number"||!Number.isFinite(f)||f<1||f>3600)throw new Error("Provide title, body and a delay from 1 to 3600 seconds.");if(p!==void 0&&(p===null||typeof p!=="object"||Array.isArray(p)))throw new Error("Local notification data must be an object.");const b=await y(t.scheduleNotificationAsync({content:{title:c,body:d,data:p??{}},trigger:{type:"timeInterval",seconds:f,repeats:false}}));await o.record("local-scheduled",{title:c,body:d,data:p,seconds:f},{notificationId:b,title:c,testId:typeof r(p).__buoyTestId==="string"?r(p).__buoyTestId:null});return{notificationId:b,transport:"local"}}};void v.getPermissions().catch(()=>{});return{actions:v,ready:w,dispose(){s=true;for(const i of a)i.remove()}}}export function instrumentExpoNotificationHandler(o,t){const e=new Map;return{...t,handleNotification:async function(...n){const s=u(n[0]);if(s.notificationId)e.set(s.notificationId,s);if(e.size>50)e.delete(e.keys().next().value);try{const a=await t.handleNotification.apply(this,n);void o.record("presentation-decision",{notification:n[0],behavior:a},u(n[0]));return a}catch(a){void o.record("presentation-error",{notification:n[0],error:a},u(n[0]));throw a}},handleError:function(...n){const s=l(n[0]);const a=s?e.get(s):void 0;if(s)e.delete(s);void o.record("presentation-error",{source:"sdk",identifier:s,error:n[1]},a??{notificationId:s});return t.handleError?.apply(this,n)}}}export function expoBackgroundMetadata(o){const t=u(o);const e=r(o);const n=r(e.data);const s=r(n.UIApplicationLaunchOptionsRemoteNotificationKey);let a={};if(typeof n.dataString==="string"){try{a=r(JSON.parse(n.dataString))}catch{}}const h=r(n.body??e.body??s.body);return{...t,testId:t.testId??l(a.__buoyTestId)??l(h.__buoyTestId),title:t.title??l(r(e.notification).title)??l(r(r(e.aps??s.aps).alert).title)}}async function m(o){let t;await Promise.race([o.catch(()=>{}),new Promise(e=>{t=setTimeout(e,250)})]);if(t)clearTimeout(t)}export function instrumentNotificationBackgroundTask(o,t){o.configure({capabilities:[...new Set([...o.getSnapshot().capabilities,"background-task"])]});return async function(...e){const n=r(e[0]).data??e[0];const s=expoBackgroundMetadata(n);await m(o.record("background-started",e[0],s));try{const a=await t.apply(this,e);await m(o.record("background-completed",{input:e[0],result:a},s));return a}catch(a){await m(o.record("background-error",{input:e[0],error:a},s));throw a}}}
|
package/lib/module/index.js
CHANGED
|
@@ -1,13 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
export * from "./types";
|
|
4
|
-
export { NotificationRecorder, expoMetadata } from "./recorder";
|
|
5
|
-
export { attachExpoNotifications, instrumentExpoNotificationHandler, instrumentNotificationBackgroundTask } from "./expo";
|
|
6
|
-
export { installExpoNotificationCapture, getNotificationRecorder, notificationSyncAdapter } from "./runtime";
|
|
7
|
-
export { NotificationToolView } from "./components/NotificationToolView";
|
|
8
|
-
export { notificationToolPreset, createNotificationTool, NotificationsModal } from "./preset";
|
|
9
|
-
export { NotificationsIcon } from "@buoy-gg/shared-ui";
|
|
10
|
-
export { composeSimulatorPayload, validateSimulatorPayload } from "./payload";
|
|
11
|
-
export { createExpoNotificationStorage } from "./storage";
|
|
12
|
-
export { NotificationTestView } from "./components/NotificationTestView";
|
|
13
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
"use strict";export*from"./types";export{NotificationRecorder,expoMetadata}from"./recorder";export{attachExpoNotifications,instrumentExpoNotificationHandler,instrumentNotificationBackgroundTask}from"./expo";export{installExpoNotificationCapture,getNotificationRecorder,notificationSyncAdapter}from"./runtime";export{NotificationToolView}from"./components/NotificationToolView";export{notificationToolPreset,createNotificationTool,NotificationsModal}from"./preset";export{NotificationsIcon}from"@buoy-gg/shared-ui";export{composeSimulatorPayload,validateSimulatorPayload}from"./payload";export{createExpoNotificationStorage}from"./storage";export{NotificationTestView}from"./components/NotificationTestView";
|
package/lib/module/json.js
CHANGED
|
@@ -1,51 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
export function object(value) {
|
|
4
|
-
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
5
|
-
}
|
|
6
|
-
export function string(value) {
|
|
7
|
-
return typeof value === "string" ? value : null;
|
|
8
|
-
}
|
|
9
|
-
export function json(value) {
|
|
10
|
-
const seen = new WeakSet();
|
|
11
|
-
function visit(v, depth) {
|
|
12
|
-
if (v == null) return null;
|
|
13
|
-
if (typeof v === "string") return v.length > 12000 ? v.slice(0, 12000) + " [truncated]" : v;
|
|
14
|
-
if (typeof v === "boolean") return v;
|
|
15
|
-
if (typeof v === "number") return Number.isFinite(v) ? v : String(v);
|
|
16
|
-
if (typeof v !== "object") return String(v);
|
|
17
|
-
if (seen.has(v)) return "[Circular]";
|
|
18
|
-
if (depth > 12) return "[Depth limit]";
|
|
19
|
-
seen.add(v);
|
|
20
|
-
if (v instanceof Error) return {
|
|
21
|
-
name: v.name,
|
|
22
|
-
message: v.message
|
|
23
|
-
};
|
|
24
|
-
if (v instanceof Date) return Number.isNaN(v.getTime()) ? "[Invalid date]" : v.toISOString();
|
|
25
|
-
if (Array.isArray(v)) return v.slice(0, 200).map(item => visit(item, depth + 1));
|
|
26
|
-
const out = {};
|
|
27
|
-
for (const key of Object.keys(v).slice(0, 200)) {
|
|
28
|
-
try {
|
|
29
|
-
Object.defineProperty(out, key, {
|
|
30
|
-
value: visit(v[key], depth + 1),
|
|
31
|
-
enumerable: true
|
|
32
|
-
});
|
|
33
|
-
} catch {
|
|
34
|
-
out[key] = "[Unreadable]";
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
return out;
|
|
38
|
-
}
|
|
39
|
-
return visit(value, 0);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/** UTF-8 size without requiring Buffer or TextEncoder in Hermes. */
|
|
43
|
-
export function byteLength(value) {
|
|
44
|
-
let bytes = 0;
|
|
45
|
-
for (const character of value) {
|
|
46
|
-
const cp = character.codePointAt(0);
|
|
47
|
-
bytes += cp <= 0x7f ? 1 : cp <= 0x7ff ? 2 : cp <= 0xffff ? 3 : 4;
|
|
48
|
-
}
|
|
49
|
-
return bytes;
|
|
50
|
-
}
|
|
51
|
-
//# sourceMappingURL=json.js.map
|
|
1
|
+
"use strict";export function object(e){return e!==null&&typeof e==="object"&&!Array.isArray(e)?e:{}}export function string(e){return typeof e==="string"?e:null}export function json(e){const r=new WeakSet;function n(t,o){if(t==null)return null;if(typeof t==="string")return t.length>12e3?t.slice(0,12e3)+" [truncated]":t;if(typeof t==="boolean")return t;if(typeof t==="number")return Number.isFinite(t)?t:String(t);if(typeof t!=="object")return String(t);if(r.has(t))return"[Circular]";if(o>12)return"[Depth limit]";r.add(t);if(t instanceof Error)return{name:t.name,message:t.message};if(t instanceof Date)return Number.isNaN(t.getTime())?"[Invalid date]":t.toISOString();if(Array.isArray(t))return t.slice(0,200).map(i=>n(i,o+1));const f={};for(const i of Object.keys(t).slice(0,200)){try{Object.defineProperty(f,i,{value:n(t[i],o+1),enumerable:true})}catch{f[i]="[Unreadable]"}}return f}return n(e,0)}export function byteLength(e){let r=0;for(const n of e){const t=n.codePointAt(0);r+=t<=127?1:t<=2047?2:t<=65535?3:4}return r}
|
package/lib/module/payload.js
CHANGED
|
@@ -1,63 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { byteLength, object } from "./json";
|
|
4
|
-
export function composeSimulatorPayload(draft) {
|
|
5
|
-
const data = {
|
|
6
|
-
...draft.data,
|
|
7
|
-
__buoyTestId: draft.testId
|
|
8
|
-
};
|
|
9
|
-
const aps = draft.silent ? {
|
|
10
|
-
"content-available": 1
|
|
11
|
-
} : {
|
|
12
|
-
alert: {
|
|
13
|
-
title: draft.title,
|
|
14
|
-
body: draft.body
|
|
15
|
-
},
|
|
16
|
-
sound: "default"
|
|
17
|
-
};
|
|
18
|
-
return JSON.stringify(draft.adapter === "expo" ? {
|
|
19
|
-
aps,
|
|
20
|
-
body: data
|
|
21
|
-
} : {
|
|
22
|
-
...data,
|
|
23
|
-
aps
|
|
24
|
-
}, null, 2);
|
|
25
|
-
}
|
|
26
|
-
export function validateSimulatorPayload(source) {
|
|
27
|
-
const errors = [];
|
|
28
|
-
const warnings = [];
|
|
29
|
-
if (typeof source !== "string") return {
|
|
30
|
-
valid: false,
|
|
31
|
-
bytes: 0,
|
|
32
|
-
errors: ["Provide the APNs payload as JSON text."],
|
|
33
|
-
warnings,
|
|
34
|
-
testId: null
|
|
35
|
-
};
|
|
36
|
-
const bytes = byteLength(source);
|
|
37
|
-
if (bytes > 4096) errors.push(`Payload is ${bytes} bytes. APNs payloads must fit in 4096 UTF-8 bytes.`);
|
|
38
|
-
let parsed;
|
|
39
|
-
try {
|
|
40
|
-
parsed = JSON.parse(source);
|
|
41
|
-
} catch {
|
|
42
|
-
errors.push("Payload is not valid JSON.");
|
|
43
|
-
}
|
|
44
|
-
const value = object(parsed);
|
|
45
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) errors.push("The payload must be a JSON object.");
|
|
46
|
-
if (!value.aps || typeof value.aps !== "object" || Array.isArray(value.aps)) errors.push('The payload needs an "aps" object.');
|
|
47
|
-
const aps = object(value.aps);
|
|
48
|
-
if (aps.alert !== undefined && typeof aps.alert !== "string" && (aps.alert === null || typeof aps.alert !== "object" || Array.isArray(aps.alert))) errors.push("aps.alert must be text or an object.");
|
|
49
|
-
if (aps.badge !== undefined && (!Number.isInteger(aps.badge) || Number(aps.badge) < 0)) errors.push("aps.badge must be a non-negative integer.");
|
|
50
|
-
for (const key of ["content-available", "mutable-content"]) if (aps[key] !== undefined && aps[key] !== 1) errors.push(`aps.${key} must be 1 when present.`);
|
|
51
|
-
if (aps["content-available"] === 1) warnings.push("Background execution depends on app configuration and OS scheduling. A successful send does not prove the task ran.");
|
|
52
|
-
if (aps["mutable-content"] === 1) warnings.push("Use real APNs delivery to verify notification service extensions.");
|
|
53
|
-
if (value.data !== undefined && value.body === undefined) warnings.push("Expo on iOS reads custom data from a top-level body object. This raw payload will be sent unchanged.");
|
|
54
|
-
const testId = object(value.body).__buoyTestId ?? value.__buoyTestId;
|
|
55
|
-
return {
|
|
56
|
-
valid: errors.length === 0,
|
|
57
|
-
bytes,
|
|
58
|
-
errors,
|
|
59
|
-
warnings,
|
|
60
|
-
testId: typeof testId === "string" ? testId : null
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
//# sourceMappingURL=payload.js.map
|
|
1
|
+
"use strict";import{byteLength as u,object as d}from"./json";export function composeSimulatorPayload(a){const e={...a.data,__buoyTestId:a.testId};const s=a.silent?{"content-available":1}:{alert:{title:a.title,body:a.body},sound:"default"};return JSON.stringify(a.adapter==="expo"?{aps:s,body:e}:{...e,aps:s},null,2)}export function validateSimulatorPayload(a){const e=[];const s=[];if(typeof a!=="string")return{valid:false,bytes:0,errors:["Provide the APNs payload as JSON text."],warnings:s,testId:null};const i=u(a);if(i>4096)e.push(`Payload is ${i} bytes. APNs payloads must fit in 4096 UTF-8 bytes.`);let o;try{o=JSON.parse(a)}catch{e.push("Payload is not valid JSON.")}const n=d(o);if(!o||typeof o!=="object"||Array.isArray(o))e.push("The payload must be a JSON object.");if(!n.aps||typeof n.aps!=="object"||Array.isArray(n.aps))e.push('The payload needs an "aps" object.');const t=d(n.aps);if(t.alert!==void 0&&typeof t.alert!=="string"&&(t.alert===null||typeof t.alert!=="object"||Array.isArray(t.alert)))e.push("aps.alert must be text or an object.");if(t.badge!==void 0&&(!Number.isInteger(t.badge)||Number(t.badge)<0))e.push("aps.badge must be a non-negative integer.");for(const r of["content-available","mutable-content"])if(t[r]!==void 0&&t[r]!==1)e.push(`aps.${r} must be 1 when present.`);if(t["content-available"]===1)s.push("Background execution depends on app configuration and OS scheduling. A successful send does not prove the task ran.");if(t["mutable-content"]===1)s.push("Use real APNs delivery to verify notification service extensions.");if(n.data!==void 0&&n.body===void 0)s.push("Expo on iOS reads custom data from a top-level body object. This raw payload will be sent unchanged.");const l=d(n.body).__buoyTestId??n.__buoyTestId;return{valid:e.length===0,bytes:i,errors:e,warnings:s,testId:typeof l==="string"?l:null}}
|