@buoy-gg/notifications 7.0.63 → 7.0.65
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/web/index.mjs +1 -1
- package/package.json +4 -4
package/lib/web/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";var He=Object.defineProperty;var pt=Object.getOwnPropertyDescriptor;var ut=Object.getOwnPropertyNames;var ht=Object.prototype.hasOwnProperty;var ft=(e,t)=>{for(var i in t)He(e,i,{get:t[i],enumerable:true})},Fe=(e,t,i,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of ut(t))!ht.call(e,r)&&r!==i&&He(e,r,{get:()=>t[r],enumerable:!(o=pt(t,r))||o.enumerable});return e},yt=(e,t,i)=>(Fe(e,t,"default"),i&&Fe(i,t,"default"));var ue=(()=>{try{let e=globalThis.Capacitor;if(e&&typeof e.isNativePlatform=="function"&&e.isNativePlatform())return e.DEBUG===true}catch{}return process.env.NODE_ENV!=="production"})();typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);var We={};ft(We,{AccessibilityInfo:()=>vt,ActivityIndicator:()=>co,Alert:()=>ho,Animated:()=>wt,AppRegistry:()=>It,AppState:()=>Me,Appearance:()=>St,BackHandler:()=>xt,Button:()=>po,CheckBox:()=>Vt,Clipboard:()=>kt,DeviceEventEmitter:()=>Zt,Dimensions:()=>Ct,Easing:()=>Tt,FlatList:()=>_e,I18nManager:()=>Nt,Image:()=>Ke,ImageBackground:()=>Ht,InteractionManager:()=>Pt,Keyboard:()=>At,KeyboardAvoidingView:()=>Ft,LayoutAnimation:()=>Et,Linking:()=>Rt,LogBox:()=>Yt,Modal:()=>so,NativeEventEmitter:()=>zt,NativeModules:()=>mt,PanResponder:()=>Lt,Picker:()=>Wt,PixelRatio:()=>Dt,Platform:()=>Se,Pressable:()=>_,ProgressBar:()=>Mt,RefreshControl:()=>_t,SafeAreaView:()=>Kt,ScrollView:()=>oe,SectionList:()=>Jt,Share:()=>jt,StatusBar:()=>$t,StyleSheet:()=>he,Switch:()=>lo,Text:()=>d,TextInput:()=>se,Touchable:()=>qt,TouchableHighlight:()=>no,TouchableNativeFeedback:()=>Ut,TouchableOpacity:()=>ro,TouchableWithoutFeedback:()=>ao,UIManager:()=>Bt,Vibration:()=>Ot,View:()=>f,VirtualizedList:()=>Gt,YellowBox:()=>Xt,findNodeHandle:()=>uo,unstable_createElement:()=>bt,useColorScheme:()=>Qt,useLocaleContext:()=>eo,useWindowDimensions:()=>to});yt(We,gt);import*as gt from"react-native-web";import{unstable_createElement as bt,NativeModules as mt,AccessibilityInfo as vt,Animated as wt,Appearance as St,AppRegistry as It,AppState as Me,BackHandler as xt,Clipboard as kt,Dimensions as Ct,Easing as Tt,I18nManager as Nt,Keyboard as At,InteractionManager as Pt,LayoutAnimation as Et,Linking as Rt,NativeEventEmitter as zt,PanResponder as Lt,PixelRatio as Dt,Platform as Se,Share as jt,StyleSheet as he,UIManager as Bt,Vibration as Ot,CheckBox as Vt,FlatList as _e,Image as Ke,ImageBackground as Ht,KeyboardAvoidingView as Ft,Picker as Wt,ProgressBar as Mt,RefreshControl as _t,SafeAreaView as Kt,SectionList as Jt,StatusBar as $t,Touchable as qt,TouchableNativeFeedback as Ut,VirtualizedList as Gt,YellowBox as Xt,LogBox as Yt,DeviceEventEmitter as Zt,useColorScheme as Qt,useLocaleContext as eo,useWindowDimensions as to}from"react-native-web";import*as B from"react-native-web";import{createElement as oo,forwardRef as io}from"react";function O(e){let t=io((o,r)=>{let{accessibilityState:a,accessibilityValue:l,...u}=o;for(let p of["busy","checked","disabled","expanded","selected"])a?.[p]!==void 0&&u[`aria-${p}`]===void 0&&(u[`aria-${p}`]=a[p]);for(let[p,c]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))l?.[p]!==void 0&&u[`aria-${c}`]===void 0&&(u[`aria-${c}`]=l[p]);return oo(e,{...u,ref:r})}),i=e.State;return i&&Object.assign(t,{State:i}),t.displayName=e.displayName??e.name??"NativeWebView",t}var f=O(B.View),d=O(B.Text),se=O(B.TextInput),ro=O(B.TouchableOpacity),no=O(B.TouchableHighlight),ao=O(B.TouchableWithoutFeedback),_=O(B.Pressable),oe=O(B.ScrollView),so=O(B.Modal),lo=O(B.Switch),co=O(B.ActivityIndicator),po=O(B.Button),uo=B.findNodeHandle,ho={alert(e,t,i,o){if(typeof document>"u")return;let r=document.createElement("dialog");r.dataset.buoyRoot="",r.setAttribute("aria-label",e),r.style.cssText="position:fixed;inset:0;margin:auto;width:min(440px,90vw);padding:24px;border:1px solid #475569;border-radius:14px;background:#17212e;color:#f1f5f9;font:14px system-ui;box-shadow:0 20px 80px #0008;z-index:2147483647";let a=document.createElement("h2");if(a.textContent=e,a.style.cssText="font-size:18px;margin:0 0 12px",r.appendChild(a),t){let c=document.createElement("p");c.textContent=t,c.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",r.appendChild(c)}let l=document.createElement("div");l.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let u=i?.length?i:[{text:"OK"}],p=()=>{r.close?.(),r.remove()};for(let c of u){let b=document.createElement("button");b.type="button",b.textContent=c.text??"OK",b.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${c.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,b.onclick=()=>{p(),c.onPress?.()},l.appendChild(b)}r.addEventListener("cancel",c=>{c.preventDefault(),o?.cancelable!==false&&(p(),o?.onDismiss?.())}),r.appendChild(l),document.body.appendChild(r),r.showModal?r.showModal():r.setAttribute("open","")}};function fo(e){if(!e.documentDirectory)throw new Error("Expo FileSystem has no persistent document directory.");let t=e.documentDirectory+"buoy-notifications/",i=o=>t+encodeURIComponent(o)+".json";return{async getItem(o){let r=i(o);return(await e.getInfoAsync(r)).exists?e.readAsStringAsync(r):null},async setItem(o,r){(await e.getInfoAsync(t)).exists||await e.makeDirectoryAsync(t,{intermediates:true}),await e.writeAsStringAsync(i(o),r)},async removeItem(o){await e.deleteAsync(i(o),{idempotent:true})},async getAllKeys(){return(await e.getInfoAsync(t)).exists?(await e.readDirectoryAsync(t)).filter(o=>o.endsWith(".json")).flatMap(o=>{try{return[decodeURIComponent(o.slice(0,-5))]}catch{return[]}}):[]}}}function yo(){try{return globalThis.localStorage??null}catch{return null}}function go(){let e=yo();return e?{storage:{async getItem(t){return e.getItem(t)},async setItem(t,i){e.setItem(t,i)},async removeItem(t){e.removeItem(t)},async getAllKeys(){let t=[];for(let i=0;i<e.length;i++){let o=e.key(i);o?.startsWith("buoy.notifications.")&&t.push(o)}return t}},durable:true}:{durable:false}}function y(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)?e:{}}function L(e){return typeof e=="string"?e:null}function Ie(e){let t=new WeakSet;function i(o,r){if(o==null)return null;if(typeof o=="string")return o.length>12e3?o.slice(0,12e3)+" [truncated]":o;if(typeof o=="boolean")return o;if(typeof o=="number")return Number.isFinite(o)?o:String(o);if(typeof o!="object")return String(o);if(t.has(o))return"[Circular]";if(r>12)return"[Depth limit]";if(t.add(o),o instanceof Error)return{name:o.name,message:o.message};if(o instanceof Date)return Number.isNaN(o.getTime())?"[Invalid date]":o.toISOString();if(Array.isArray(o))return o.slice(0,200).map(l=>i(l,r+1));let a={};for(let l of Object.keys(o).slice(0,200))try{Object.defineProperty(a,l,{value:i(o[l],r+1),enumerable:true})}catch{a[l]="[Unreadable]"}return a}return i(e,0)}function ie(e){let t=0;for(let i of e){let o=i.codePointAt(0);t+=o<=127?1:o<=2047?2:o<=65535?3:4}return t}var xe="buoy.notifications.v1.",ke=xe+"session",Je=xe+"tokens",fe=xe+"event.",Ce=16*1024,bo=512*1024,mo=200,Te=class{constructor(e={}){this.options=e;this.state={version:1,ready:false,provider:null,providerVersion:null,platform:"unknown",appId:null,capabilities:[],durable:false,storageError:null,evicted:0,session:null,events:[],tokens:[],permissions:null,presented:null};this.listeners=new Set;this.sequence=0;this.queue=Promise.resolve();this.getSnapshot=()=>this.state;this.subscribe=t=>(this.listeners.add(t),()=>{this.listeners.delete(t)});this.now=e.now??Date.now,this.processId=e.processId??`${this.now().toString(36)}-${Math.random().toString(36).slice(2)}`,this.state.durable=!!e.storage&&e.durable===true,this.ready=this.hydrate(),this.queue=this.ready}update(e){this.state={...this.state,...e};for(let t of this.listeners)try{t()}catch{}}configure(e){this.update(e)}allowed(){return this.options.enabled?.()??true}storageFailure(e){this.update({storageError:e instanceof Error?e.message:String(e),durable:false})}serial(e){let t=this.queue.then(e);return this.queue=t.catch(()=>{}),t}async hydrate(){if(!this.allowed()){this.update({ready:true});return}if(this.options.durability)try{this.update({durable:await this.options.durability})}catch(i){this.storageFailure(i)}let e=this.options.storage,t=false;if(e)try{let i=await e.getItem(ke);if(t=i==="null",i){let l=JSON.parse(i);l&&typeof l.runId=="string"&&Number.isFinite(l.expiresAt)&&l.expiresAt>this.now()&&this.update({session:l})}let o=await e.getItem(Je);if(o){let l=JSON.parse(o);Array.isArray(l)&&this.update({tokens:l.filter(u=>u&&["apns","fcm","expo"].includes(u.type)&&typeof u.value=="string").slice(-10)})}let r=(await e.getAllKeys()).filter(l=>l.startsWith(fe)).sort(),a=[];for(let l of r)try{let u=await e.getItem(l);if(!u||ie(u)>Ce){await e.removeItem(l);continue}let p=JSON.parse(u);typeof p.id=="string"&&typeof p.kind=="string"&&Number.isFinite(p.capturedAt)?a.push(p):await e.removeItem(l)}catch{await e.removeItem(l)}a.sort((l,u)=>l.capturedAt-u.capturedAt||l.sequence-u.sequence||l.id.localeCompare(u.id)),this.update({events:a}),await this.prune()}catch(i){this.storageFailure(i)}if(this.options.autoStart&&!this.state.session&&!t){let i=this.now(),o={runId:this.processId,startedAt:i,expiresAt:i+1800*1e3};try{await e?.setItem(ke,JSON.stringify(o))}catch(r){this.storageFailure(r)}this.update({session:o})}this.update({ready:true})}async setCaptureSession(e,t=1800*1e3){if(!this.allowed())throw new Error("Notification capture is disabled in this build.");if(e!==null&&(typeof e!="string"||!e.trim()||e.length>128))throw new Error("runId must contain 1 to 128 characters, or be null to stop capture.");if(!Number.isFinite(t)||t<1e3||t>3600*1e3)throw new Error("Capture duration must be between 1 second and 1 hour.");return this.serial(async()=>{let i=this.now(),o=e===null?null:{runId:e,startedAt:i,expiresAt:i+t};try{this.options.storage&&await this.options.storage.setItem(ke,JSON.stringify(o))}catch(r){throw this.storageFailure(r),new Error("Could not persist the capture session. Keep the app open and check storage.")}return this.update({session:o}),{session:o,durable:this.state.durable}})}record(e,t,i={}){let o=this.now(),r=this.options.appState?.()??"unknown",a=Ie(t);return this.serial(async()=>{if(!this.allowed())return null;let l=this.state.session;if(!l||l.expiresAt<=o)return l&&this.update({session:null}),null;let u=(b,R=512)=>typeof b=="string"?b.slice(0,R):null,p=u(i.dedupeKey,2048);if(p&&this.state.events.some(b=>b.dedupeKey===p))return null;let c={id:`${this.processId}-${++this.sequence}`,processId:this.processId,sequence:this.sequence,capturedAt:o,runId:l.runId,kind:e,provider:u(i.provider,64)??this.state.provider??"app",observedAppState:r,notificationId:u(i.notificationId),testId:u(i.testId),title:u(i.title,1024),actionIdentifier:u(i.actionIdentifier),...p?{dedupeKey:p}:{},raw:a};ie(JSON.stringify(c))>Ce&&(c.raw={note:"Payload exceeded the 16 KiB capture limit."},c.truncated=true),this.update({events:[...this.state.events,c]});try{await this.options.storage?.setItem(fe+c.id,JSON.stringify(c))}catch(b){this.storageFailure(b)}try{await this.prune()}catch(b){this.storageFailure(b)}return c})}async prune(){let e=[...this.state.events],t=e.map(r=>ie(JSON.stringify(r))),i=t.reduce((r,a)=>r+a,0),o=[];for(;e.length>mo||i>bo;)o.push(e.shift()),i-=t.shift();o.length&&this.update({events:e,evicted:this.state.evicted+o.length});for(let r of o)await this.options.storage?.removeItem(fe+r.id)}async clearCapturedEvents(){return this.serial(async()=>{let e=this.state.events;for(let t of e)await this.options.storage?.removeItem(fe+t.id);return this.update({events:[],evicted:0}),{cleared:true}})}async observeToken(e,t,i={}){if(this.allowed()){if(!t||t.length>8192)throw new Error("The notification token is empty or too long.");return this.serial(async()=>{let o={type:e,value:t,observedAt:this.now(),...typeof i.projectId=="string"?{projectId:i.projectId.slice(0,256)}:{},...typeof i.environment=="string"?{environment:i.environment.slice(0,256)}:{}},r=[...this.state.tokens.filter(a=>!(a.type===e&&a.projectId===i.projectId&&a.environment===i.environment)),o].slice(-10);this.update({tokens:r});try{await this.options.storage?.setItem(Je,JSON.stringify(r))}catch(a){this.storageFailure(a)}})}}setPermissions(e){let t=Ie(e);this.update({permissions:ie(JSON.stringify(t))<=Ce?t:{note:"Permission result exceeded the capture limit."}})}setPresented(e){let t=Ie(e);ie(JSON.stringify(t))<=128*1024?this.update({presented:t}):this.update({presented:{note:"System tray result exceeded 128 KiB. Inspect fewer presented notifications in the app.",count:Array.isArray(e)?e.length:null}})}async flush(){await this.queue}};function X(e){let t=y(e),i=y(t.notification??e),o=y(i.request),r=y(o.content),a=y(y(o.trigger).payload),l=y(r.data??a.body);return{notificationId:L(o.identifier),testId:L(l.__buoyTestId),title:L(r.title),actionIdentifier:L(t.actionIdentifier)}}function vo(e){let t=y(e),i=y(t.notification);return JSON.stringify([y(i.request).identifier,i.date,t.actionIdentifier,t.userText])}function $e(e){if(!e||typeof e!="object")return;let t={};typeof e.appName=="string"&&(t.appName=e.appName.trim().slice(0,80)),typeof e.iconUri=="string"&&e.iconUri.length<=32768&&/^data:image\/(png|jpeg|webp);base64,[A-Za-z0-9+/]+={0,2}$/.test(e.iconUri)&&(t.iconUri=e.iconUri);for(let i of["backgroundColor","textColor"])typeof e[i]=="string"&&/^#[0-9a-f]{6}$/i.test(e[i])&&(t[i]=e[i]);return Object.keys(t).length?t:void 0}function le(e,t=15e3){return new Promise((i,o)=>{let r=setTimeout(()=>o(new Error("Notification SDK timed out. Check permission and network settings, then retry.")),t);e.then(a=>{clearTimeout(r),i(a)},a=>{clearTimeout(r),o(a)})})}function qe(e,t,i){let o=["received","responses","permissions","device-token"];(t.getLastNotificationResponse||t.getLastNotificationResponseAsync)&&o.push("startup-response"),t.getPresentedNotificationsAsync&&o.push("presented"),t.scheduleNotificationAsync&&o.push("local-scheduling"),i.projectId&&t.getExpoPushTokenAsync&&o.push("expo-token"),e.configure({preview:$e(i.preview),provider:"expo",platform:i.platform,appId:i.appId??null,providerVersion:i.providerVersion??null,capabilities:o});let r=false,a=[],l=(c,b=false)=>{r||!c||e.record(b?"startup-response":"response",c,{...X(c),dedupeKey:vo(c)})};try{a.push(t.addNotificationReceivedListener(c=>{r||e.record("received",c,X(c))})),a.push(t.addNotificationResponseReceivedListener(c=>l(c))),a.push(t.addPushTokenListener(c=>{!r&&(c.type==="ios"||c.type==="android")&&e.observeToken(c.type==="ios"?"apns":"fcm",c.data).catch(()=>{})}))}catch(c){for(let b of a)b.remove();throw c}let u=Promise.resolve().then(()=>t.getLastNotificationResponse?.()??t.getLastNotificationResponseAsync?.()).then(c=>l(c,true));u.catch(()=>{});let p={async getPermissions(){let c=await le(t.getPermissionsAsync());return e.setPermissions(c),e.getSnapshot().permissions},async listPresented(){if(!t.getPresentedNotificationsAsync)throw new Error("This notification SDK cannot list presented notifications.");let c=await le(t.getPresentedNotificationsAsync());return e.setPresented(c),e.getSnapshot().presented},async refreshToken(c){let{type:b}=y(c);if(b==="expo"){if(!t.getExpoPushTokenAsync||!i.projectId)throw new Error("Set projectId in installExpoNotificationCapture before requesting an Expo token.");let P=await le(t.getExpoPushTokenAsync({projectId:i.projectId}));return await e.observeToken("expo",P.data,{projectId:i.projectId}),{type:"expo",value:P.data}}if(b!=="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.");let R=await le(t.getDevicePushTokenAsync());if(R.type!=="ios"&&R.type!=="android")throw new Error("This platform does not provide an APNs or FCM token.");return await e.observeToken(R.type==="ios"?"apns":"fcm",R.data),{type:R.type==="ios"?"apns":"fcm",value:R.data}},async scheduleLocal(c){if(!t.scheduleNotificationAsync)throw new Error("This notification SDK cannot schedule local notifications.");let{title:b,body:R,data:P,seconds:T}=y(c);if(typeof b!="string"||typeof R!="string"||typeof T!="number"||!Number.isFinite(T)||T<1||T>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.");let J=await le(t.scheduleNotificationAsync({content:{title:b,body:R,data:P??{}},trigger:{type:"timeInterval",seconds:T,repeats:false}}));return await e.record("local-scheduled",{title:b,body:R,data:P,seconds:T},{notificationId:J,title:b,testId:typeof y(P).__buoyTestId=="string"?y(P).__buoyTestId:null}),{notificationId:J,transport:"local"}}};return p.getPermissions().catch(()=>{}),{actions:p,ready:u,dispose(){r=true;for(let c of a)c.remove()}}}function wo(e,t){let i=new Map;return{...t,handleNotification:async function(...o){let r=X(o[0]);r.notificationId&&i.set(r.notificationId,r),i.size>50&&i.delete(i.keys().next().value);try{let a=await t.handleNotification.apply(this,o);return e.record("presentation-decision",{notification:o[0],behavior:a},X(o[0])),a}catch(a){throw e.record("presentation-error",{notification:o[0],error:a},X(o[0])),a}},handleError:function(...o){let r=L(o[0]),a=r?i.get(r):void 0;return r&&i.delete(r),e.record("presentation-error",{source:"sdk",identifier:r,error:o[1]},a??{notificationId:r}),t.handleError?.apply(this,o)}}}function So(e){let t=X(e),i=y(e),o=y(i.data),r=y(o.UIApplicationLaunchOptionsRemoteNotificationKey),a={};if(typeof o.dataString=="string")try{a=y(JSON.parse(o.dataString))}catch{}let l=y(o.body??i.body??r.body);return{...t,testId:t.testId??L(a.__buoyTestId)??L(l.__buoyTestId),title:t.title??L(y(i.notification).title)??L(y(y(i.aps??r.aps).alert).title)}}async function Ne(e){let t;await Promise.race([e.catch(()=>{}),new Promise(i=>{t=setTimeout(i,250)})]),t&&clearTimeout(t)}function Io(e,t){return e.configure({capabilities:[...new Set([...e.getSnapshot().capabilities,"background-task"])]}),(async function(...i){let o=y(i[0]).data??i[0],r=So(o);await Ne(e.record("background-started",i[0],r));try{let a=await t.apply(this,i);return await Ne(e.record("background-completed",{input:i[0],result:a},r)),a}catch(a){throw await Ne(e.record("background-error",{input:i[0],error:a},r)),a}})}var re="PushNotifications",ce="LocalNotifications";function ye(e){let t=y(e),i=y(t.notification??e),o=y(i.data??i.extra),r=y(o.body),a=i.id;return{notificationId:typeof a=="number"?String(a):L(a),testId:L(o.__buoyTestId)??L(r.__buoyTestId),title:L(i.title)??L(y(y(o.aps).alert).title),actionIdentifier:L(t.actionId)}}function de(e,t=15e3){return new Promise((i,o)=>{let r=setTimeout(()=>o(new Error("The notification plugin timed out. Check permission and network settings, then retry.")),t);e.then(a=>{clearTimeout(r),i(a)},a=>{clearTimeout(r),o(a)})})}function Ue(e,t,i){let o=t.hasCapacitorPlugin(re),r=t.hasCapacitorPlugin(ce),a=["received","responses","permissions"];o&&a.push("device-token","presented"),r&&a.push("local-scheduling"),r&&!o&&a.push("presented"),e.configure({preview:$e(i.preview),provider:"capacitor",platform:i.platform,appId:i.appId??null,providerVersion:i.providerVersion??null,capabilities:a}),t.installCapacitorBridge(),i.appId||t.loadCapacitorAppHost?.().then(g=>{g?.bundleId&&e.configure({appId:g.bundleId})}).catch(()=>{});let l=i.platform==="ios"?"apns":"fcm",u=0,p=new Set,c=250,b=new Map,R=(g,w)=>{let m=b.get(g);if(m!==void 0&&w-m<c)return null;if(b.set(g,w),b.size>100)for(let[x,C]of b)w-C>=c&&b.delete(x);return w},P=g=>{if(g.plugin!==re&&g.plugin!==ce)return;let w=g.result,m=`${g.plugin}:${g.method}:${JSON.stringify(w??null).slice(0,1500)}`;if(g.kind==="event"&&R(m,g.start)===null)return;let x=`${m}:${g.start}`;if(g.kind==="event")switch(g.method){case"registration":{let C=L(y(w).value);C&&e.observeToken(l,C).catch(()=>{});return}case"pushNotificationReceived":case"localNotificationReceived":e.record("received",w,{...ye(w),provider:"capacitor",dedupeKey:x});return;case"pushNotificationActionPerformed":case"localNotificationActionPerformed":e.record("response",w,{...ye(w),provider:"capacitor",dedupeKey:x});return;default:return}if(!(g.kind!=="promise"||g.ok!==true))if(g.method==="checkPermissions"||g.method==="requestPermissions")e.setPermissions({plugin:g.plugin,...y(w)});else if(g.plugin===ce&&g.method==="schedule")for(let C of Array.isArray(g.options.notifications)?g.options.notifications:[]){let k=ye(C);e.record("local-scheduled",C,{...k,provider:"capacitor"})}else g.method==="getDeliveredNotifications"&&e.setPresented(y(w).notifications??w)},T=()=>{let g=t.getCapacitorCalls();for(let m of g)m.seq<=u||p.has(m.seq)||m.kind==="promise"&&m.end===void 0||(p.add(m.seq),P(m));let w=g[0]?.seq??0;if(w>u+1){u=w-1;for(let m of Array.from(p))m<=u&&p.delete(m)}},J=t.subscribeCapacitorCalls(T);T();let F=o?re:ce,j={async getPermissions(){if(!o&&!r)throw new Error("Install @capacitor/push-notifications or @capacitor/local-notifications in the app.");let g=await de(t.callCapacitorAsApp(F,"checkPermissions"));return e.setPermissions({plugin:F,...y(g)}),e.getSnapshot().permissions},async listPresented(){if(!o&&!r)throw new Error("This app has no notification plugin that can list presented notifications.");let g=await de(t.callCapacitorNative(F,"getDeliveredNotifications"));return e.setPresented(y(g).notifications??g),e.getSnapshot().presented},async refreshToken(g){let{type:w}=y(g);if(w==="expo")throw new Error("Expo push tokens need expo-notifications; this app uses Capacitor.");if(w!=="device")throw new Error('Token type must be "device".');if(!o)throw new Error("Install @capacitor/push-notifications to register a device token.");let m=null,x=new Promise((C,k)=>{t.listenCapacitorNative(re,"registration",z=>{let M=L(y(z).value);M&&C(M)}).then(z=>{m=z.remove}),t.listenCapacitorNative(re,"registrationError",z=>{k(new Error(L(y(z).error)??"Push registration failed."))}).then(z=>{let M=m;m=async()=>{await M?.(),await z.remove()}})});try{await de(t.callCapacitorNative(re,"register"));let C=await de(x);return await e.observeToken(l,C),{type:l,value:C}}finally{m?.()}},async scheduleLocal(g){if(!r)throw new Error("Install @capacitor/local-notifications to schedule local notifications.");let{title:w,body:m,data:x,seconds:C}=y(g);if(typeof w!="string"||typeof m!="string"||typeof C!="number"||!Number.isFinite(C)||C<1||C>3600)throw new Error("Provide title, body and a delay from 1 to 3600 seconds.");if(x!==void 0&&(x===null||typeof x!="object"||Array.isArray(x)))throw new Error("Local notification data must be an object.");let k=Math.floor(Math.random()*2e9)+1,z={id:k,title:w,body:m,extra:x??{},schedule:{at:new Date(Date.now()+C*1e3).toISOString()}};return await de(t.callCapacitorNative(ce,"schedule",{notifications:[z]})),await e.record("local-scheduled",{title:w,body:m,data:x,seconds:C},{notificationId:String(k),title:w,testId:typeof y(x).__buoyTestId=="string"?y(x).__buoyTestId:null,provider:"capacitor"}),{notificationId:String(k),transport:"local"}}};return j.getPermissions().catch(()=>{}),{actions:j,ready:e.ready,dispose(){J()}}}import*as Ge from"@buoy-gg/license/web";var ge=globalThis;function Ae(e=false){return typeof ue<"u"&&ue||e===true}function Pe(){return ge.__buoyNotificationsV1?.recorder??null}function Xe(e){let t=ge.__buoyNotificationsV1;if(!t){let i=e.storage?{storage:e.storage,durable:e.durable===true}:go();t={recorder:new Te({...i,enabled:()=>Ae(e.enableInRelease),appState:()=>Me.currentState??"unknown",autoStart:true})},ge.__buoyNotificationsV1=t}return t}function xo(e,t={}){if(!Ae(t.enableInRelease))return null;let i=JSON.stringify([t.platform??Se.OS,t.appId,t.providerVersion,t.projectId,t.enableInRelease,t.preview]),o=Xe(t);return(o.sdk!==e||o.key!==i)&&(o.attachment?.dispose(),o.attachment=qe(o.recorder,e,{...t,platform:t.platform??Se.OS}),o.sdk=e,o.key=i),o.recorder}function Ye(e={}){let t=Ge.capacitorPlatform();if(!t||!Ae(e.enableInRelease))return null;let i=JSON.stringify(["capacitor",e.appId,e.providerVersion,e.enableInRelease,e.preview]),o=Xe(e);return(o.sdk!=="capacitor"||o.key!==i)&&(o.attachment?.dispose(),o.attachment=Ue(o.recorder,Ge,{...e,platform:t}),o.sdk="capacitor",o.key=i),o.recorder}var Ze=new Te;function Y(){let e=ge.__buoyNotificationsV1;if(!e)throw new Error("Install notification capture in the app entry point (installExpoNotificationCapture), before rendering the root component. Capacitor apps capture by themselves in debug builds.");return e}var ne={version:1,getSnapshot:()=>(Pe()??Ze).getSnapshot(),subscribe:e=>(Pe()??Ze).subscribe(e),actions:{getSnapshot:()=>ne.getSnapshot(),getCapabilities:()=>{let{ready:e,provider:t,providerVersion:i,platform:o,appId:r,capabilities:a,durable:l,storageError:u}=ne.getSnapshot();return{ready:e,provider:t,providerVersion:i,platform:o,appId:r,capabilities:a,durable:l,storageError:u}},getEvent(e){let{id:t}=y(e);if(typeof t!="string")throw new Error("Provide the captured event id.");return Y().recorder.getSnapshot().events.find(i=>i.id===t)??null},async setCaptureSession(e){let{runId:t,durationMs:i}=y(e);if(typeof t!="string"&&t!==null)throw new Error("Provide runId, or null to stop capture.");if(i!==void 0&&typeof i!="number")throw new Error("durationMs must be a number.");return Y().recorder.setCaptureSession(t,i)},clearCapturedEvents:()=>Y().recorder.clearCapturedEvents(),getPermissions:()=>Y().attachment.actions.getPermissions(),listPresented:()=>Y().attachment.actions.listPresented(),refreshToken:e=>Y().attachment.actions.refreshToken(e),scheduleLocal:e=>Y().attachment.actions.scheduleLocal(e)}};import{useEffect as ko,useMemo as Qe,useState as Z}from"react";import{ChevronDown as Co,ChevronLeft as To,ChevronRight as et,Copy as tt,ModalHeader as Ee,NightBadge as be,NightCard as U,NightRows as ot,NightSectionLabel as G,NightSegmented as No,NotificationsIcon as Ao,PowerToggleButton as Po,Search as Eo,Settings as Ro,ToolEmptyState as Re,Trash2 as zo,X as Lo,copyToClipboard as Do,night as D,useSafeAreaInsets as jo}from"@buoy-gg/shared-ui/web";import{DataViewer as Bo}from"@buoy-gg/shared-ui/web/dataViewer";import{useRef as Oo,useState as Q}from"react";import{NightSegmented as Vo,night as ae}from"@buoy-gg/shared-ui/web";import{useEffect as Ho,useState as it}from"react";import{CheckCircle as Fo,ChevronDown as Wo,ChevronRight as Mo,NotificationsIcon as rt,XCircle as _o,night as A,useSafeAreaInsets as Ko}from"@buoy-gg/shared-ui/web";import{jsx as N,jsxs as V}from"react/jsx-runtime";function nt(e){let[t,i]=it(false);Ho(()=>i(false),[e.appearance?.iconUri]);let o=e.appearance?.textColor?{color:e.appearance.textColor}:void 0,[r,a]=it(false),l=Ko({minBottom:12});return V(f,{style:I.root,children:[N(oe,{testID:"notification-test-scroll",style:I.root,contentContainerStyle:I.scroll,keyboardShouldPersistTaps:"handled",children:V(f,{style:I.content,children:[V(f,{style:I.intro,children:[N(d,{accessibilityRole:"header",style:I.heading,children:"Test a notification"}),N(d,{style:I.caption,children:"Send a test notification to your app."})]}),e.destination,e.previewNote?N(d,{style:I.caption,children:e.previewNote}):V(f,{style:[I.preview,e.appearance?.backgroundColor?{backgroundColor:e.appearance.backgroundColor,borderColor:e.appearance.backgroundColor}:void 0],accessibilityLabel:"Notification preview",children:[V(f,{style:I.row,children:[e.appearance?.iconUri&&!t?N(Ke,{testID:"buoy-internal-notification-preview",source:{uri:e.appearance.iconUri},accessibilityLabel:`${e.appearance.appName??e.appName} icon`,style:I.appIcon,onError:()=>i(true)}):N(f,{style:I.iconFallback,children:N(rt,{size:22,color:A.color.accent})}),N(d,{numberOfLines:1,style:[I.caption,I.appName,o],children:e.appearance?.appName??e.appName}),N(d,{style:[I.caption,o],children:"now"})]}),N(se,{accessibilityLabel:"Notification title",placeholder:"Title",placeholderTextColor:A.color.placeholder,value:e.title,onChangeText:e.onTitleChange,style:[I.input,I.title,o],editable:!e.busy}),N(se,{accessibilityLabel:"Notification message",placeholder:"Message",placeholderTextColor:A.color.placeholder,value:e.message,onChangeText:e.onMessageChange,style:[I.input,o],editable:!e.busy})]}),e.result&&V(f,{accessibilityRole:"summary",accessibilityLiveRegion:"polite",testID:"notification-test-result",style:I.result,children:[V(f,{style:I.row,children:[e.result.failed?N(_o,{size:16,color:A.color.danger}):N(Fo,{size:16,color:A.color.accent}),N(d,{style:I.resultTitle,children:e.result.title})]}),N(d,{style:I.caption,children:e.result.message}),N(_,{accessibilityRole:"button",accessibilityLabel:"View activity",onPress:e.onViewActivity,style:I.secondary,children:N(d,{style:I.secondaryText,children:"View activity"})})]}),V(f,{children:[V(_,{accessibilityRole:"button",accessibilityLabel:"Notification options",accessibilityState:{expanded:r},onPress:()=>a(!r),style:I.options,children:[r?N(Wo,{size:12,color:A.color.textSecondary}):N(Mo,{size:12,color:A.color.textSecondary}),N(d,{style:I.caption,children:"Options"})]}),r&&e.options]})]})}),V(f,{style:[I.footer,{paddingBottom:l.bottom}],children:[!!e.error&&N(d,{accessibilityRole:"alert",style:I.error,children:e.error}),!!e.notice&&N(d,{accessibilityLiveRegion:"polite",style:I.caption,children:e.notice}),V(f,{style:I.footerRow,children:[N(d,{style:[I.caption,I.hint],children:e.hint}),V(_,{accessibilityRole:"button",accessibilityLabel:e.busy?"Sending\u2026":"Send notification",accessibilityState:{disabled:e.disabled||e.busy},disabled:e.disabled||e.busy,onPress:e.onSend,style:({pressed:u})=>[I.send,(e.disabled||e.busy)&&I.disabled,u&&I.pressed],children:[N(rt,{size:15,color:A.color.onAccent}),N(d,{style:I.sendText,children:e.busy?"Sending\u2026":"Send notification"})]})]})]})]})}var I=he.create({root:{flex:1,minHeight:0,minWidth:0},scroll:{padding:16,flexGrow:1},content:{width:"100%",maxWidth:620,alignSelf:"center",gap:20},intro:{gap:8,paddingTop:8},heading:{color:A.color.text,fontSize:22,fontWeight:"600",letterSpacing:-.5},caption:{color:A.color.textSecondary,fontSize:12,lineHeight:18},row:{flexDirection:"row",alignItems:"center",gap:8},appName:{flex:1,fontWeight:"600"},appIcon:{width:36,height:36,borderRadius:8},iconFallback:{width:36,height:36,alignItems:"center",justifyContent:"center",borderRadius:8,backgroundColor:A.color.fillSecondary},preview:{padding:16,gap:8,borderWidth:1,borderColor:A.color.glassBorder,borderRadius:20,backgroundColor:A.color.glass},input:{color:A.color.text,fontSize:14,padding:6,minHeight:36},title:{fontSize:16,fontWeight:"600"},result:{gap:10,padding:16,borderWidth:1,borderColor:A.color.glassBorder,borderRadius:14},resultTitle:{color:A.color.text,fontWeight:"500",fontSize:13,flexShrink:1},secondary:{alignSelf:"flex-start",paddingHorizontal:14,paddingVertical:8,borderRadius:24,backgroundColor:A.color.fillSecondary},secondaryText:{color:A.color.accent,fontSize:13},options:{flexDirection:"row",alignItems:"center",gap:6,paddingVertical:12},footer:{padding:14,gap:8,borderTopWidth:1,borderTopColor:A.color.separator},footerRow:{flexDirection:"row",flexWrap:"wrap",alignItems:"center",justifyContent:"space-between",gap:12},hint:{flexGrow:1,flexShrink:1,flexBasis:200},send:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:8,borderRadius:24,paddingHorizontal:18,paddingVertical:12,backgroundColor:A.color.accent},sendText:{color:A.color.onAccent,fontSize:13,fontWeight:"600"},disabled:{opacity:.4},pressed:{opacity:.8},error:{color:A.color.danger,fontSize:12,lineHeight:18}});import{jsx as K,jsxs as me}from"react/jsx-runtime";function Jo({snapshot:e,onAction:t,onViewActivity:i}){let[o,r]=Q("Test notification"),[a,l]=Q("Tap to open the app."),[u,p]=Q("{}"),[c,b]=Q("1"),[R,P]=Q(false),T=Oo(false),[J,F]=Q(null),[j,g]=Q(null),w={},m=null;try{if(w=JSON.parse(u),!w||typeof w!="object"||Array.isArray(w))throw new Error}catch{m="Custom data must be a JSON object. Open Options to edit it."}async function x(){if(T.current||m)return;T.current=true,P(true),g(null),F(null);let E={testId:`buoy-local-${Date.now()}-${Math.random().toString(36).slice(2)}`,startedAt:Date.now(),appId:e?.appId??null};try{await t("setCaptureSession",{runId:E.testId,durationMs:18e5}),await t("scheduleLocal",{title:o,body:a,data:{...w,__buoyTestId:E.testId},seconds:Number(c)}),g(E)}catch(te){F(te instanceof Error?te.message:String(te))}finally{T.current=false,P(false)}}let C=j&&j.appId===e?.appId?e.events.filter(E=>E.testId===j.testId&&E.capturedAt>=j.startedAt):[],k=C.some(E=>E.kind==="received"),z=C.some(E=>E.kind==="response"||E.kind==="startup-response"),M=C.some(E=>E.kind==="app-outcome"),$=!!e?.capabilities.includes("local-scheduling");return K(nt,{title:o,message:a,onTitleChange:r,onMessageChange:l,appName:"This app",appearance:e?.preview,destination:me(f,{style:H.destination,children:[me(f,{style:H.field,children:[K(d,{style:H.label,children:"Device"}),K(d,{style:H.value,children:"This device"})]}),me(f,{style:H.field,children:[K(d,{style:H.label,children:"Delivery"}),K(d,{style:H.value,children:"Local notification"})]})]}),options:me(f,{style:H.options,children:[K(d,{style:H.label,children:"Send after"}),K(Vo,{tabs:[{key:"1",label:"1 second"},{key:"10",label:"10 seconds"}],activeKey:c,onChange:b,size:"sm",glass:true}),K(d,{style:H.label,children:"Custom data"}),K(se,{accessibilityLabel:"Notification custom data",value:u,onChangeText:p,multiline:true,autoCapitalize:"none",autoCorrect:false,style:H.json}),K(d,{style:H.label,children:"Use the delay to leave the app before delivery. Simulator push and raw APNs payloads are available on desktop."})]}),result:j?{title:M?"App reported an outcome":z?"Notification tapped":k?"Received by app":"Notification scheduled",message:z?"Open Activity to inspect the app\u2019s response.":"Tap the notification to test what opens."}:null,onViewActivity:i,onSend:()=>{x()},busy:R,disabled:!$||!!m,error:J??m,hint:$?c==="10"?"You have 10 seconds to leave the app.":"Sends locally on this device after one second.":"Connect Expo notification capture to send a local test."})}var H=he.create({destination:{flexDirection:"row",gap:12},field:{flex:1,gap:7},label:{color:ae.color.textSecondary,fontSize:12,lineHeight:18},value:{color:ae.color.text,fontSize:13,borderWidth:1,borderColor:ae.color.glassBorder,backgroundColor:ae.color.glass,borderRadius:10,padding:11},options:{gap:12},json:{color:ae.color.text,fontSize:12,minHeight:100,textAlignVertical:"top",padding:12,borderWidth:1,borderColor:ae.color.glassBorder,borderRadius:10}});import{monoFont as pe,night as v}from"@buoy-gg/shared-ui/web";var s=he.create({root:{flex:1,minHeight:0,backgroundColor:"transparent"},fill:{flex:1,minHeight:0},inlineHeader:{paddingHorizontal:12,paddingVertical:8,borderBottomWidth:1,borderBottomColor:v.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:v.color.textTertiary},liveDot:{backgroundColor:v.color.accent},caption:{color:v.color.textSecondary,fontSize:12,lineHeight:17},provider:{color:v.color.textSecondary,fontSize:11,marginLeft:"auto",fontFamily:pe},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:v.color.glass,borderWidth:1,borderColor:v.color.glassBorder,borderRadius:v.radius.row},searchInput:{flex:1,minWidth:0,height:"100%",color:v.color.text,fontSize:13,padding:0},clearSearch:{padding:6},iconButton:{width:34,height:34,alignItems:"center",justifyContent:"center",backgroundColor:v.color.buttonSurface,borderRadius:8,borderWidth:1,borderColor:v.color.border},event:{backgroundColor:v.color.glass,borderRadius:v.radius.input,borderWidth:1,borderColor:v.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:v.color.textSecondary,fontFamily:pe,fontSize:10},eventSubject:{flexDirection:"row",alignItems:"center",gap:8},eventTitle:{flex:1,color:v.color.text,fontSize:15,fontWeight:"500"},eventMeta:{color:v.color.textSecondary,fontFamily:pe,fontSize:10,lineHeight:15},resultCount:{color:v.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:v.radius.pill,backgroundColor:v.color.fillSecondary,alignSelf:"flex-start"},buttonText:{color:v.color.accent,fontSize:13,fontWeight:"600"},primaryButton:{backgroundColor:v.color.accent},primaryButtonText:{color:v.color.onAccent},pressed:{opacity:.7},disabled:{opacity:.4},detailTitle:{color:v.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:v.color.text,fontFamily:pe,fontSize:12,lineHeight:18},disclosure:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingHorizontal:16,paddingVertical:14},disclosureTitle:{color:v.color.text,fontSize:13,fontWeight:"500"},jsonBody:{padding:10,borderTopWidth:1,borderTopColor:v.color.separator},token:{color:v.color.text,fontFamily:pe,fontSize:12,lineHeight:20},bodyText:{color:v.color.text,fontSize:14,lineHeight:21},footnote:{color:v.color.textSecondary,fontSize:12,lineHeight:18,marginTop:8,marginHorizontal:4},emptyFootnote:{color:v.color.textSecondary,fontSize:12,lineHeight:18,textAlign:"center",marginHorizontal:28},sectionActions:{flexDirection:"row",marginBottom:10},warning:{color:v.color.warning,fontSize:12,lineHeight:18},notice:{color:v.color.accent,backgroundColor:v.color.glass,paddingHorizontal:16,paddingVertical:10,fontSize:12,lineHeight:18},errorNotice:{color:v.color.danger,backgroundColor:v.color.glass,paddingHorizontal:16,paddingVertical:10,fontSize:12,lineHeight:18},errorText:{color:v.color.danger}});import{Fragment as ze,jsx as n,jsxs as h}from"react/jsx-runtime";var Le={received:"App received",response:"Notification response","startup-response":"Response recovered at startup","presentation-decision":"Presentation decision","presentation-error":"Presentation error","background-started":"Background task started","background-completed":"Background task completed","background-error":"Background task failed","app-outcome":"App outcome","local-scheduled":"Local notification scheduled"};function at(e){return e.includes("error")?"danger":e==="startup-response"?"warning":e==="received"||e==="app-outcome"?"accent":"neutral"}function W({label:e,onPress:t,disabled:i,primary:o,icon:r}){return h(_,{accessibilityRole:"button",accessibilityLabel:e,accessibilityState:{disabled:!!i},disabled:i,onPress:t,style:({pressed:a})=>[s.button,o&&s.primaryButton,a&&s.pressed,i&&s.disabled],children:[r,n(d,{style:[s.buttonText,o&&s.primaryButtonText],children:e})]})}function ee({label:e,value:t}){return h(f,{style:s.field,children:[n(d,{style:[s.caption,s.fieldLabel],children:e}),n(d,{selectable:true,style:s.value,children:t})]})}function ve({title:e,value:t,initiallyOpen:i=true}){let[o,r]=Z(i),a=JSON.stringify(t??null),l=Qe(()=>JSON.parse(a),[a]);return h(U,{glass:true,children:[h(_,{accessibilityRole:"button",accessibilityLabel:e,accessibilityState:{expanded:o},onPress:()=>r(u=>!u),style:s.disclosure,children:[n(d,{style:s.disclosureTitle,children:e}),o?n(Co,{size:14,color:D.color.textSecondary}):n(et,{size:14,color:D.color.textSecondary})]}),o&&n(f,{style:s.jsonBody,children:n(Bo,{title:"",data:l,rawMode:true,initialExpanded:true,showTypeFilter:false})})]})}function st({snapshot:e,onAction:t,sender:i,activeTab:o,onTabChange:r,renderShell:a}){let[l,u]=Z("send"),p=o??l,[c,b]=Z(""),[R,P]=Z(null),[T,J]=Z(false),[F,j]=Z(null),[,g]=Z(0),w=jo({minBottom:16}),m=e?.session?.expiresAt;ko(()=>{if(!m||m<=Date.now())return;let S=setTimeout(()=>g(q=>q+1),m-Date.now()+1);return()=>clearTimeout(S)},[m]);let x=!!m&&m>Date.now(),C=Qe(()=>(e?.events??[]).filter(S=>JSON.stringify(S).toLowerCase().includes(c.trim().toLowerCase())).slice().reverse(),[e?.events,c]),k=e?.events.find(S=>S.id===R),z=e?.events.length??0,M=!!e?.provider;function $(S){u(S),r?.(S),j(null)}async function E(S,q){if(T)return false;J(true),j(null);try{return await t(S,q),true}catch(we){return j({text:we instanceof Error?we.message:String(we),error:true}),false}finally{J(false)}}let te=()=>{E("setCaptureSession",{runId:`capture-${Date.now()}`,durationMs:18e5})},je=()=>{E("setCaptureSession",{runId:null})};async function Be(S){let q=await Do(S);j({text:q?"Copied to clipboard.":"Clipboard is unavailable. Select the text to copy it.",error:!q})}let dt=[{key:"send",label:"Test"},{key:"events",label:`Activity (${z})`}],Oe=h(Ee,{children:[n(Ee.Content,{title:"",noMargin:true,children:n(No,{tabs:dt,activeKey:p,onChange:$,size:"sm",glass:true})}),h(Ee.Actions,{children:[n(_,{accessibilityRole:"button",accessibilityLabel:"Notification settings",onPress:()=>$(p==="setup"||p==="tokens"?"send":"setup"),style:s.iconButton,children:n(Ro,{size:16,color:p==="setup"||p==="tokens"?D.color.accent:D.color.textSecondary})}),p!=="send"&&n(Po,{isEnabled:x,onToggle:x?je:te,disabled:!M||T,accessibilityLabel:x?"Stop notification capture":"Start notification capture",testID:"notifications-capture"})]})]}),Ve=h(f,{style:s.root,children:[M&&p!=="send"&&h(f,{style:s.status,children:[h(f,{style:s.statusLabel,children:[n(f,{style:[s.dot,x&&s.liveDot]}),n(d,{style:s.caption,children:x?"Recording":"Capture stopped"})]}),p!=="events"&&n(d,{style:s.caption,children:e.durable?"Persistent history":"Memory only"}),p!=="events"&&h(d,{style:s.provider,children:[e.provider," \xB7 ",e.platform]})]}),e?.storageError&&h(d,{accessibilityRole:"alert",style:s.errorNotice,children:["Storage: ",e.storageError]}),F&&n(d,{accessibilityRole:F.error?"alert":"text",style:[s.notice,F.error&&s.errorText],children:F.text}),!i&&n(f,{style:p==="send"?s.fill:{display:"none"},children:n(Jo,{snapshot:e,onAction:t,onViewActivity:()=>$("events")})}),p==="send"?i??null:M?h(ze,{children:[p==="events"&&h(ze,{children:[h(f,{style:s.searchRow,children:[h(f,{style:s.searchField,children:[n(Eo,{size:14,color:D.color.textSecondary}),n(se,{accessibilityLabel:"Filter notification events",placeholder:"Search notifications\u2026",placeholderTextColor:D.color.placeholder,value:c,onChangeText:S=>{b(S),P(null)},autoCapitalize:"none",autoCorrect:false,style:s.searchInput}),!!c&&n(_,{accessibilityRole:"button",accessibilityLabel:"Clear notification search",onPress:()=>b(""),style:s.clearSearch,children:n(Lo,{size:12,color:D.color.textSecondary})})]}),n(_,{accessibilityRole:"button",accessibilityLabel:"Clear captured events",disabled:T||!z,accessibilityState:{disabled:T||!z},style:[s.iconButton,(T||!z)&&s.disabled],onPress:()=>{E("clearCapturedEvents").then(S=>{S&&P(null)})},children:n(zo,{size:14,color:D.color.textSecondary})})]}),k?h(oe,{style:s.fill,contentContainerStyle:[s.content,{paddingBottom:w.bottom}],keyboardShouldPersistTaps:"handled",children:[h(f,{style:s.actionRow,children:[n(W,{label:"Back to events",onPress:()=>P(null),icon:n(To,{size:14,color:D.color.accent})}),n(W,{label:"Copy event JSON",onPress:()=>{Be(k)},icon:n(tt,{size:14,color:D.color.accent})})]}),h(U,{glass:true,padded:true,children:[n(be,{label:Le[k.kind]??k.kind,tone:at(k.kind)}),n(d,{style:s.detailTitle,children:k.title??"Notification event"}),n(d,{style:s.caption,children:new Date(k.capturedAt).toLocaleString()})]}),h(f,{children:[n(G,{children:"Observation"}),n(U,{glass:true,children:h(ot,{children:[n(ee,{label:"App state at callback",value:k.observedAppState}),k.testId&&n(ee,{label:"Test ID",value:k.testId}),k.notificationId&&n(ee,{label:"Notification ID",value:k.notificationId}),k.actionIdentifier&&n(ee,{label:"Action",value:k.actionIdentifier})]})})]}),k.kind==="startup-response"&&n(d,{style:s.footnote,children:"Recovered from the SDK cache. This alone does not establish why the app launched."}),k.truncated&&n(d,{style:s.warning,children:"This payload was truncated when captured."}),n(ve,{title:"Payload",value:k.raw}),n(ve,{title:"Full event",value:k,initiallyOpen:false})]}):n(_e,{data:C,keyExtractor:S=>S.id,style:s.fill,contentContainerStyle:[s.eventList,{paddingBottom:w.bottom}],keyboardShouldPersistTaps:"handled",initialNumToRender:15,ListHeaderComponent:c?h(d,{style:s.resultCount,children:[C.length," of ",z," events"]}):null,ListFooterComponent:e.evicted>0?h(d,{style:s.footnote,children:[e.evicted," older records removed by the history limit."]}):null,ListEmptyComponent:n(Re,{otto:c?"sad":x?"listening":"paused",title:c?"No matching events":x?"Waiting for notifications":"Capture is stopped",message:c?"Try another title, test ID, or payload value.":x?"Send a notification from Buoy Desktop or your app. Background alerts can reach the system tray before an app callback runs.":"Start capture with the power button, then send a notification."}),renderItem:({item:S})=>n($o,{event:S,onPress:()=>P(S.id)})})]}),p==="tokens"&&h(oe,{style:s.fill,contentContainerStyle:[s.content,{paddingBottom:w.bottom}],keyboardShouldPersistTaps:"handled",children:[h(f,{children:[n(W,{label:"Back to settings",onPress:()=>$("setup")}),n(G,{children:"Registration"}),h(U,{glass:true,padded:true,children:[n(d,{style:s.bodyText,children:"Register a token to test delivery through your push provider."}),h(f,{style:s.actionRow,children:[n(W,{label:"Register device token",onPress:()=>{E("refreshToken",{type:"device"})},disabled:T,primary:true}),n(W,{label:"Register Expo token",onPress:()=>{E("refreshToken",{type:"expo"})},disabled:T||!e.capabilities.includes("expo-token")})]})]}),n(d,{style:s.footnote,children:"Registration runs only when you or your app request it. Simulator sends work without a token."})]}),e.tokens.length===0?n(Re,{otto:"listening",title:"No tokens observed",message:"Register a device token above, or let your app register one."}):e.tokens.map((S,q)=>h(f,{children:[n(G,{children:S.type.toUpperCase()+" token"}),h(U,{glass:true,padded:true,children:[h(f,{style:s.actionRow,children:[n(be,{label:S.type,tone:"accent"}),S.environment&&n(d,{style:s.caption,children:S.environment})]}),n(d,{selectable:true,style:s.token,children:S.value}),S.projectId&&h(d,{selectable:true,style:s.caption,children:["Project: ",S.projectId]}),h(d,{style:s.caption,children:["Observed ",new Date(S.observedAt).toLocaleString()]}),n(f,{style:s.actionRow,children:n(W,{label:"Copy "+S.type.toUpperCase()+" token",onPress:()=>{Be(S.value)},icon:n(tt,{size:14,color:D.color.accent})})})]})]},S.type+"-"+q))]}),p==="setup"&&h(oe,{style:s.fill,contentContainerStyle:[s.content,{paddingBottom:w.bottom}],keyboardShouldPersistTaps:"handled",children:[h(f,{children:[n(W,{label:"Device tokens",onPress:()=>$("tokens")}),n(G,{children:"Capture session"}),h(U,{glass:true,padded:true,children:[h(f,{style:s.actionRow,children:[n(be,{label:x?"Recording":"Stopped",tone:x?"accent":"neutral"}),n(d,{style:s.caption,children:x?"Until "+new Date(m).toLocaleTimeString():"Ready when you are"})]}),h(f,{style:s.actionRow,children:[n(W,{label:"Arm capture for 30 minutes",onPress:te,disabled:T,primary:true}),n(W,{label:"Stop capture",onPress:je,disabled:T||!x})]})]}),n(d,{style:s.footnote,children:e.durable?"History is saved on the app and survives app and desktop restarts.":"History is held in memory. Keep the app running to retain it."})]}),h(f,{children:[n(G,{children:"Connected app"}),n(U,{glass:true,children:h(ot,{children:[n(ee,{label:"App",value:e.appId??"Not supplied"}),n(ee,{label:"Provider",value:[e.provider,e.providerVersion].filter(Boolean).join(" ")}),n(ee,{label:"Platform",value:e.platform})]})})]}),h(f,{children:[n(G,{children:"Permissions"}),n(f,{style:s.sectionActions,children:n(W,{label:"Refresh permissions",disabled:T,onPress:()=>{E("getPermissions")}})}),n(ve,{title:"Permission settings",value:e.permissions})]}),h(f,{children:[n(G,{children:"System tray"}),n(f,{style:s.sectionActions,children:n(W,{label:"Inspect system tray",disabled:T||!e.capabilities.includes("presented"),onPress:()=>{E("listPresented")}})}),n(ve,{title:"Currently presented",value:e.presented}),n(d,{style:s.footnote,children:"Notifications currently in the system tray. Captured history is in Activity."})]}),h(f,{children:[n(G,{children:"Capabilities"}),n(U,{glass:true,padded:true,children:n(f,{style:s.actionRow,children:e.capabilities.map(S=>n(be,{label:S},S))})})]})]})]}):h(oe,{children:[n(Re,{otto:"paused",title:"Connect notification capture",message:"Install @buoy-gg/notifications and call installExpoNotificationCapture in the app entry point. Use an app-specific development build for remote notifications."}),n(d,{style:s.emptyFootnote,children:"The desktop sender works with any installed app. Inspection needs the capture integration."})]})]});return n(ze,{children:a?a({header:Oe,body:Ve}):h(f,{style:s.root,children:[n(f,{style:s.inlineHeader,children:Oe}),Ve]})})}function $o({event:e,onPress:t}){let i=at(e.kind),o=i==="danger"?D.color.danger:i==="warning"?D.color.warning:i==="accent"?D.color.accent:D.color.textSecondary;return h(_,{accessibilityRole:"button",accessibilityLabel:(Le[e.kind]??e.kind)+": "+(e.title??e.testId??e.notificationId??"notification"),onPress:t,style:({pressed:r})=>[s.event,r&&s.pressed],children:[h(f,{style:s.eventTop,children:[h(f,{style:s.eventKind,children:[n(Ao,{size:13,color:o}),n(d,{numberOfLines:1,style:[s.eventLabel,{color:o}],children:Le[e.kind]??e.kind})]}),n(d,{style:s.timestamp,children:new Date(e.capturedAt).toLocaleTimeString()})]}),h(f,{style:s.eventSubject,children:[n(d,{numberOfLines:1,style:s.eventTitle,children:e.title??e.testId??e.notificationId??"Notification event"}),n(et,{size:14,color:D.color.textTertiary})]}),h(d,{numberOfLines:1,style:s.eventMeta,children:[e.observedAppState,e.truncated?" \xB7 Truncated":""]})]})}import{useSyncExternalStore as qo}from"react";import{createToolFactory as Uo,defineToolPreset as Go,JsModal as Xo,NotificationsIcon as Yo}from"@buoy-gg/shared-ui/web";import{jsx as De}from"react/jsx-runtime";function lt(e){let t=qo(ne.subscribe,ne.getSnapshot);return De(st,{snapshot:t,renderShell:({header:i,body:o})=>De(Xo,{...e,persistenceKey:e.persistenceKey??"buoy-notifications",variant:"night",header:{showToggleButton:true,customContent:i},enablePersistence:true,initialMode:"bottomSheet",disableScrollWrapper:true,children:o}),onAction:async(i,o)=>{let r=ne.actions[i];if(!r)throw new Error("This notification action is unavailable.");return r(o)}})}var ct=Go({id:"push-notifications",name:"NOTIFICATIONS",description:"Send a test notification and inspect how the app responds",slot:"both",icon:({size:e,color:t})=>De(Yo,{size:e,color:t}),component:lt}),Zo=Uo(ct);import{NotificationsIcon as Qo}from"@buoy-gg/shared-ui/web";function ei(e){let t={...e.data,__buoyTestId:e.testId},i=e.silent?{"content-available":1}:{alert:{title:e.title,body:e.body},sound:"default"};return JSON.stringify(e.adapter==="expo"?{aps:i,body:t}:{...t,aps:i},null,2)}function ti(e){let t=[],i=[];if(typeof e!="string")return{valid:false,bytes:0,errors:["Provide the APNs payload as JSON text."],warnings:i,testId:null};let o=ie(e);o>4096&&t.push(`Payload is ${o} bytes. APNs payloads must fit in 4096 UTF-8 bytes.`);let r;try{r=JSON.parse(e)}catch{t.push("Payload is not valid JSON.")}let a=y(r);(!r||typeof r!="object"||Array.isArray(r))&&t.push("The payload must be a JSON object."),(!a.aps||typeof a.aps!="object"||Array.isArray(a.aps))&&t.push('The payload needs an "aps" object.');let l=y(a.aps);l.alert!==void 0&&typeof l.alert!="string"&&(l.alert===null||typeof l.alert!="object"||Array.isArray(l.alert))&&t.push("aps.alert must be text or an object."),l.badge!==void 0&&(!Number.isInteger(l.badge)||Number(l.badge)<0)&&t.push("aps.badge must be a non-negative integer.");for(let p of["content-available","mutable-content"])l[p]!==void 0&&l[p]!==1&&t.push(`aps.${p} must be 1 when present.`);l["content-available"]===1&&i.push("Background execution depends on app configuration and OS scheduling. A successful send does not prove the task ran."),l["mutable-content"]===1&&i.push("Use real APNs delivery to verify notification service extensions."),a.data!==void 0&&a.body===void 0&&i.push("Expo on iOS reads custom data from a top-level body object. This raw payload will be sent unchanged.");let u=y(a.body).__buoyTestId??a.__buoyTestId;return{valid:t.length===0,bytes:o,errors:t,warnings:i,testId:typeof u=="string"?u:null}}var oi=(()=>{try{return globalThis.Capacitor?.isNativePlatform?.()===true}catch{return false}})();oi&&typeof ue<"u"&&ue&&Ye();export{Te as NotificationRecorder,nt as NotificationTestView,st as NotificationToolView,Qo as NotificationsIcon,lt as NotificationsModal,Ue as attachCapacitorNotifications,qe as attachExpoNotifications,ye as capacitorMetadata,ei as composeSimulatorPayload,fo as createExpoNotificationStorage,Zo as createNotificationTool,X as expoMetadata,Pe as getNotificationRecorder,Ye as installCapacitorNotificationCapture,xo as installExpoNotificationCapture,wo as instrumentExpoNotificationHandler,Io as instrumentNotificationBackgroundTask,ne as notificationSyncAdapter,ct as notificationToolPreset,ti as validateSimulatorPayload};
|
|
1
|
+
"use client";var Ke=Object.defineProperty;var bt=Object.getOwnPropertyDescriptor;var mt=Object.getOwnPropertyNames;var vt=Object.prototype.hasOwnProperty;var wt=(e,t)=>{for(var i in t)Ke(e,i,{get:t[i],enumerable:true})},Me=(e,t,i,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of mt(t))!vt.call(e,r)&&r!==i&&Ke(e,r,{get:()=>t[r],enumerable:!(o=bt(t,r))||o.enumerable});return e},St=(e,t,i)=>(Me(e,t,"default"),i&&Me(i,t,"default"));var he=(()=>{try{let e=globalThis.Capacitor;if(e&&typeof e.isNativePlatform=="function"&&e.isNativePlatform())return e.DEBUG===true}catch{}return process.env.NODE_ENV!=="production"})();typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);var We={};wt(We,{AccessibilityInfo:()=>Ct,ActivityIndicator:()=>Io,Alert:()=>Co,Animated:()=>Tt,AppRegistry:()=>At,AppState:()=>_e,Appearance:()=>Nt,BackHandler:()=>Pt,Button:()=>xo,CheckBox:()=>_t,Clipboard:()=>Et,DeviceEventEmitter:()=>ro,Dimensions:()=>Lt,Easing:()=>Rt,FlatList:()=>Je,I18nManager:()=>zt,Image:()=>$e,ImageBackground:()=>Jt,InteractionManager:()=>jt,Keyboard:()=>Dt,KeyboardAvoidingView:()=>$t,LayoutAnimation:()=>Bt,Linking:()=>Ot,LogBox:()=>io,Modal:()=>wo,NativeEventEmitter:()=>Vt,NativeModules:()=>kt,PanResponder:()=>Ht,Picker:()=>qt,PixelRatio:()=>Ft,Platform:()=>Ie,Pressable:()=>W,ProgressBar:()=>Ut,RefreshControl:()=>Gt,SafeAreaView:()=>Xt,ScrollView:()=>oe,SectionList:()=>Yt,Share:()=>Kt,StatusBar:()=>Zt,StyleSheet:()=>fe,Switch:()=>So,Text:()=>h,TextInput:()=>le,Touchable:()=>Qt,TouchableHighlight:()=>mo,TouchableNativeFeedback:()=>eo,TouchableOpacity:()=>bo,TouchableWithoutFeedback:()=>vo,UIManager:()=>Mt,Vibration:()=>Wt,View:()=>y,VirtualizedList:()=>to,YellowBox:()=>oo,findNodeHandle:()=>ko,unstable_createElement:()=>xt,useColorScheme:()=>no,useLocaleContext:()=>ao,useWindowDimensions:()=>so});St(We,It);import*as It from"react-native-web";import{unstable_createElement as xt,NativeModules as kt,AccessibilityInfo as Ct,Animated as Tt,Appearance as Nt,AppRegistry as At,AppState as _e,BackHandler as Pt,Clipboard as Et,Dimensions as Lt,Easing as Rt,I18nManager as zt,Keyboard as Dt,InteractionManager as jt,LayoutAnimation as Bt,Linking as Ot,NativeEventEmitter as Vt,PanResponder as Ht,PixelRatio as Ft,Platform as Ie,Share as Kt,StyleSheet as fe,UIManager as Mt,Vibration as Wt,CheckBox as _t,FlatList as Je,Image as $e,ImageBackground as Jt,KeyboardAvoidingView as $t,Picker as qt,ProgressBar as Ut,RefreshControl as Gt,SafeAreaView as Xt,SectionList as Yt,StatusBar as Zt,Touchable as Qt,TouchableNativeFeedback as eo,VirtualizedList as to,YellowBox as oo,LogBox as io,DeviceEventEmitter as ro,useColorScheme as no,useLocaleContext as ao,useWindowDimensions as so}from"react-native-web";import*as B from"react-native-web";import{createElement as xe,forwardRef as qe,useCallback as lo,useRef as co}from"react";import{useEffect as po,useState as uo}from"react";import{createPortal as ho}from"react-dom";var fo='-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';import{jsx as yo}from"react/jsx-runtime";var se=Symbol.for("@buoy-gg/portal-host"),Ue=e=>{if(!(e instanceof Element))return false;if(e.closest("input, textarea, select"))return true;let t=e.closest("[contenteditable]")?.getAttribute("contenteditable")?.toLowerCase();return t===""||t==="true"||t==="plaintext-only"};function Ge(){let e=document;if(e[se])return e[se].host;let t=document.createElement("div");t.dataset.buoyPortalHost="",Object.assign(t.style,{position:"fixed",inset:"0",zIndex:"2147483647",pointerEvents:"none",fontFamily:fo});let i=()=>{let d=document.fullscreenElement,A=d&&d.tagName!=="CANVAS"?d:document.body;t.parentElement!==A&&A.appendChild(t)},o=new Map,r=d=>{(!t.contains(d.target)||!Ue(d.target))&&o.set(d.code||d.key,{key:d.key,code:d.code,location:d.location,keyCode:d.keyCode,which:d.which,altKey:d.altKey,ctrlKey:d.ctrlKey,metaKey:d.metaKey,shiftKey:d.shiftKey})},n=d=>{o.delete(d.code||d.key)},l=()=>o.clear(),u=()=>{let d=[...o.values()];o.clear();for(let A of d)document.dispatchEvent(new KeyboardEvent("keyup",{...A,bubbles:true}))},p=d=>{Ue(d.target)&&d.stopPropagation()},c=d=>d.stopPropagation();return i(),document.addEventListener("fullscreenchange",i),document.addEventListener("keydown",r,true),document.addEventListener("keyup",n,true),window.addEventListener("blur",l),t.addEventListener("focusin",u),t.addEventListener("keydown",p),t.addEventListener("keyup",p),t.addEventListener("keypress",p),t.addEventListener("wheel",c,{passive:true}),e[se]={host:t,users:0,dispose:()=>{document.removeEventListener("fullscreenchange",i),document.removeEventListener("keydown",r,true),document.removeEventListener("keyup",n,true),window.removeEventListener("blur",l),t.remove(),delete e[se]}},t}function go({children:e}){let[t,i]=uo(null);return po(()=>{let o=Ge(),r=document[se];return r.users++,i(o),()=>{--r.users===0&&r.dispose()}},[]),t?ho(yo("div",{"data-buoy-root":"",style:{display:"contents",pointerEvents:"auto"},children:e}),t):null}function O(e){let t=qe((o,r)=>{let{accessibilityState:n,accessibilityValue:l,...u}=o;for(let p of["busy","checked","disabled","expanded","selected"])n?.[p]!==void 0&&u[`aria-${p}`]===void 0&&(u[`aria-${p}`]=n[p]);for(let[p,c]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))l?.[p]!==void 0&&u[`aria-${c}`]===void 0&&(u[`aria-${c}`]=l[p]);return xe(e,{...u,ref:r})}),i=e.State;return i&&Object.assign(t,{State:i}),t.displayName=e.displayName??e.name??"NativeWebView",t}var y=O(B.View),h=O(B.Text),le=O(B.TextInput),bo=O(B.TouchableOpacity),mo=O(B.TouchableHighlight),vo=O(B.TouchableWithoutFeedback),W=O(B.Pressable),oe=O(B.ScrollView),Xe=qe((e,t)=>{let i=co(null),o=lo(r=>{if(r){let n=r;for(;n.parentElement&&n.parentElement!==document.body;)n=n.parentElement;n.parentElement===document.body&&(i.current=n,Object.assign(n.style,{position:"relative",zIndex:"2147483647",pointerEvents:"auto"}),Ge().appendChild(n))}else i.current&&(document.body.appendChild(i.current),i.current=null);typeof t=="function"?t(r):t&&(t.current=r)},[t]);return xe(go,null,xe(B.Modal,{...e,ref:o}))});Xe.displayName="Modal";var wo=O(Xe),So=O(B.Switch),Io=O(B.ActivityIndicator),xo=O(B.Button),ko=B.findNodeHandle,Co={alert(e,t,i,o){if(typeof document>"u")return;let r=document.createElement("dialog");r.dataset.buoyRoot="",r.setAttribute("aria-label",e),r.style.cssText="position:fixed;inset:0;margin:auto;width:min(440px,90vw);padding:24px;border:1px solid #475569;border-radius:14px;background:#17212e;color:#f1f5f9;font:14px system-ui;box-shadow:0 20px 80px #0008;z-index:2147483647";let n=document.createElement("h2");if(n.textContent=e,n.style.cssText="font-size:18px;margin:0 0 12px",r.appendChild(n),t){let c=document.createElement("p");c.textContent=t,c.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",r.appendChild(c)}let l=document.createElement("div");l.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let u=i?.length?i:[{text:"OK"}],p=()=>{r.close?.(),r.remove()};for(let c of u){let d=document.createElement("button");d.type="button",d.textContent=c.text??"OK",d.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${c.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,d.onclick=()=>{p(),c.onPress?.()},l.appendChild(d)}r.addEventListener("cancel",c=>{c.preventDefault(),o?.cancelable!==false&&(p(),o?.onDismiss?.())}),r.appendChild(l),document.body.appendChild(r),r.showModal?r.showModal():r.setAttribute("open","")}};function To(e){if(!e.documentDirectory)throw new Error("Expo FileSystem has no persistent document directory.");let t=e.documentDirectory+"buoy-notifications/",i=o=>t+encodeURIComponent(o)+".json";return{async getItem(o){let r=i(o);return(await e.getInfoAsync(r)).exists?e.readAsStringAsync(r):null},async setItem(o,r){(await e.getInfoAsync(t)).exists||await e.makeDirectoryAsync(t,{intermediates:true}),await e.writeAsStringAsync(i(o),r)},async removeItem(o){await e.deleteAsync(i(o),{idempotent:true})},async getAllKeys(){return(await e.getInfoAsync(t)).exists?(await e.readDirectoryAsync(t)).filter(o=>o.endsWith(".json")).flatMap(o=>{try{return[decodeURIComponent(o.slice(0,-5))]}catch{return[]}}):[]}}}function No(){try{return globalThis.localStorage??null}catch{return null}}function Ao(){let e=No();return e?{storage:{async getItem(t){return e.getItem(t)},async setItem(t,i){e.setItem(t,i)},async removeItem(t){e.removeItem(t)},async getAllKeys(){let t=[];for(let i=0;i<e.length;i++){let o=e.key(i);o?.startsWith("buoy.notifications.")&&t.push(o)}return t}},durable:true}:{durable:false}}function g(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)?e:{}}function z(e){return typeof e=="string"?e:null}function ke(e){let t=new WeakSet;function i(o,r){if(o==null)return null;if(typeof o=="string")return o.length>12e3?o.slice(0,12e3)+" [truncated]":o;if(typeof o=="boolean")return o;if(typeof o=="number")return Number.isFinite(o)?o:String(o);if(typeof o!="object")return String(o);if(t.has(o))return"[Circular]";if(r>12)return"[Depth limit]";if(t.add(o),o instanceof Error)return{name:o.name,message:o.message};if(o instanceof Date)return Number.isNaN(o.getTime())?"[Invalid date]":o.toISOString();if(Array.isArray(o))return o.slice(0,200).map(l=>i(l,r+1));let n={};for(let l of Object.keys(o).slice(0,200))try{Object.defineProperty(n,l,{value:i(o[l],r+1),enumerable:true})}catch{n[l]="[Unreadable]"}return n}return i(e,0)}function ie(e){let t=0;for(let i of e){let o=i.codePointAt(0);t+=o<=127?1:o<=2047?2:o<=65535?3:4}return t}var Ce="buoy.notifications.v1.",Te=Ce+"session",Ye=Ce+"tokens",ye=Ce+"event.",Ne=16*1024,Po=512*1024,Eo=200,Ae=class{constructor(e={}){this.options=e;this.state={version:1,ready:false,provider:null,providerVersion:null,platform:"unknown",appId:null,capabilities:[],durable:false,storageError:null,evicted:0,session:null,events:[],tokens:[],permissions:null,presented:null};this.listeners=new Set;this.sequence=0;this.queue=Promise.resolve();this.getSnapshot=()=>this.state;this.subscribe=t=>(this.listeners.add(t),()=>{this.listeners.delete(t)});this.now=e.now??Date.now,this.processId=e.processId??`${this.now().toString(36)}-${Math.random().toString(36).slice(2)}`,this.state.durable=!!e.storage&&e.durable===true,this.ready=this.hydrate(),this.queue=this.ready}update(e){this.state={...this.state,...e};for(let t of this.listeners)try{t()}catch{}}configure(e){this.update(e)}allowed(){return this.options.enabled?.()??true}storageFailure(e){this.update({storageError:e instanceof Error?e.message:String(e),durable:false})}serial(e){let t=this.queue.then(e);return this.queue=t.catch(()=>{}),t}async hydrate(){if(!this.allowed()){this.update({ready:true});return}if(this.options.durability)try{this.update({durable:await this.options.durability})}catch(i){this.storageFailure(i)}let e=this.options.storage,t=false;if(e)try{let i=await e.getItem(Te);if(t=i==="null",i){let l=JSON.parse(i);l&&typeof l.runId=="string"&&Number.isFinite(l.expiresAt)&&l.expiresAt>this.now()&&this.update({session:l})}let o=await e.getItem(Ye);if(o){let l=JSON.parse(o);Array.isArray(l)&&this.update({tokens:l.filter(u=>u&&["apns","fcm","expo"].includes(u.type)&&typeof u.value=="string").slice(-10)})}let r=(await e.getAllKeys()).filter(l=>l.startsWith(ye)).sort(),n=[];for(let l of r)try{let u=await e.getItem(l);if(!u||ie(u)>Ne){await e.removeItem(l);continue}let p=JSON.parse(u);typeof p.id=="string"&&typeof p.kind=="string"&&Number.isFinite(p.capturedAt)?n.push(p):await e.removeItem(l)}catch{await e.removeItem(l)}n.sort((l,u)=>l.capturedAt-u.capturedAt||l.sequence-u.sequence||l.id.localeCompare(u.id)),this.update({events:n}),await this.prune()}catch(i){this.storageFailure(i)}if(this.options.autoStart&&!this.state.session&&!t){let i=this.now(),o={runId:this.processId,startedAt:i,expiresAt:i+1800*1e3};try{await e?.setItem(Te,JSON.stringify(o))}catch(r){this.storageFailure(r)}this.update({session:o})}this.update({ready:true})}async setCaptureSession(e,t=1800*1e3){if(!this.allowed())throw new Error("Notification capture is disabled in this build.");if(e!==null&&(typeof e!="string"||!e.trim()||e.length>128))throw new Error("runId must contain 1 to 128 characters, or be null to stop capture.");if(!Number.isFinite(t)||t<1e3||t>3600*1e3)throw new Error("Capture duration must be between 1 second and 1 hour.");return this.serial(async()=>{let i=this.now(),o=e===null?null:{runId:e,startedAt:i,expiresAt:i+t};try{this.options.storage&&await this.options.storage.setItem(Te,JSON.stringify(o))}catch(r){throw this.storageFailure(r),new Error("Could not persist the capture session. Keep the app open and check storage.")}return this.update({session:o}),{session:o,durable:this.state.durable}})}record(e,t,i={}){let o=this.now(),r=this.options.appState?.()??"unknown",n=ke(t);return this.serial(async()=>{if(!this.allowed())return null;let l=this.state.session;if(!l||l.expiresAt<=o)return l&&this.update({session:null}),null;let u=(d,A=512)=>typeof d=="string"?d.slice(0,A):null,p=u(i.dedupeKey,2048);if(p&&this.state.events.some(d=>d.dedupeKey===p))return null;let c={id:`${this.processId}-${++this.sequence}`,processId:this.processId,sequence:this.sequence,capturedAt:o,runId:l.runId,kind:e,provider:u(i.provider,64)??this.state.provider??"app",observedAppState:r,notificationId:u(i.notificationId),testId:u(i.testId),title:u(i.title,1024),actionIdentifier:u(i.actionIdentifier),...p?{dedupeKey:p}:{},raw:n};ie(JSON.stringify(c))>Ne&&(c.raw={note:"Payload exceeded the 16 KiB capture limit."},c.truncated=true),this.update({events:[...this.state.events,c]});try{await this.options.storage?.setItem(ye+c.id,JSON.stringify(c))}catch(d){this.storageFailure(d)}try{await this.prune()}catch(d){this.storageFailure(d)}return c})}async prune(){let e=[...this.state.events],t=e.map(r=>ie(JSON.stringify(r))),i=t.reduce((r,n)=>r+n,0),o=[];for(;e.length>Eo||i>Po;)o.push(e.shift()),i-=t.shift();o.length&&this.update({events:e,evicted:this.state.evicted+o.length});for(let r of o)await this.options.storage?.removeItem(ye+r.id)}async clearCapturedEvents(){return this.serial(async()=>{let e=this.state.events;for(let t of e)await this.options.storage?.removeItem(ye+t.id);return this.update({events:[],evicted:0}),{cleared:true}})}async observeToken(e,t,i={}){if(this.allowed()){if(!t||t.length>8192)throw new Error("The notification token is empty or too long.");return this.serial(async()=>{let o={type:e,value:t,observedAt:this.now(),...typeof i.projectId=="string"?{projectId:i.projectId.slice(0,256)}:{},...typeof i.environment=="string"?{environment:i.environment.slice(0,256)}:{}},r=[...this.state.tokens.filter(n=>!(n.type===e&&n.projectId===i.projectId&&n.environment===i.environment)),o].slice(-10);this.update({tokens:r});try{await this.options.storage?.setItem(Ye,JSON.stringify(r))}catch(n){this.storageFailure(n)}})}}setPermissions(e){let t=ke(e);this.update({permissions:ie(JSON.stringify(t))<=Ne?t:{note:"Permission result exceeded the capture limit."}})}setPresented(e){let t=ke(e);ie(JSON.stringify(t))<=128*1024?this.update({presented:t}):this.update({presented:{note:"System tray result exceeded 128 KiB. Inspect fewer presented notifications in the app.",count:Array.isArray(e)?e.length:null}})}async flush(){await this.queue}};function X(e){let t=g(e),i=g(t.notification??e),o=g(i.request),r=g(o.content),n=g(g(o.trigger).payload),l=g(r.data??n.body);return{notificationId:z(o.identifier),testId:z(l.__buoyTestId),title:z(r.title),actionIdentifier:z(t.actionIdentifier)}}function Lo(e){let t=g(e),i=g(t.notification);return JSON.stringify([g(i.request).identifier,i.date,t.actionIdentifier,t.userText])}function Ze(e){if(!e||typeof e!="object")return;let t={};typeof e.appName=="string"&&(t.appName=e.appName.trim().slice(0,80)),typeof e.iconUri=="string"&&e.iconUri.length<=32768&&/^data:image\/(png|jpeg|webp);base64,[A-Za-z0-9+/]+={0,2}$/.test(e.iconUri)&&(t.iconUri=e.iconUri);for(let i of["backgroundColor","textColor"])typeof e[i]=="string"&&/^#[0-9a-f]{6}$/i.test(e[i])&&(t[i]=e[i]);return Object.keys(t).length?t:void 0}function ce(e,t=15e3){return new Promise((i,o)=>{let r=setTimeout(()=>o(new Error("Notification SDK timed out. Check permission and network settings, then retry.")),t);e.then(n=>{clearTimeout(r),i(n)},n=>{clearTimeout(r),o(n)})})}function Qe(e,t,i){let o=["received","responses","permissions","device-token"];(t.getLastNotificationResponse||t.getLastNotificationResponseAsync)&&o.push("startup-response"),t.getPresentedNotificationsAsync&&o.push("presented"),t.scheduleNotificationAsync&&o.push("local-scheduling"),i.projectId&&t.getExpoPushTokenAsync&&o.push("expo-token"),e.configure({preview:Ze(i.preview),provider:"expo",platform:i.platform,appId:i.appId??null,providerVersion:i.providerVersion??null,capabilities:o});let r=false,n=[],l=(c,d=false)=>{r||!c||e.record(d?"startup-response":"response",c,{...X(c),dedupeKey:Lo(c)})};try{n.push(t.addNotificationReceivedListener(c=>{r||e.record("received",c,X(c))})),n.push(t.addNotificationResponseReceivedListener(c=>l(c))),n.push(t.addPushTokenListener(c=>{!r&&(c.type==="ios"||c.type==="android")&&e.observeToken(c.type==="ios"?"apns":"fcm",c.data).catch(()=>{})}))}catch(c){for(let d of n)d.remove();throw c}let u=Promise.resolve().then(()=>t.getLastNotificationResponse?.()??t.getLastNotificationResponseAsync?.()).then(c=>l(c,true));u.catch(()=>{});let p={async getPermissions(){let c=await ce(t.getPermissionsAsync());return e.setPermissions(c),e.getSnapshot().permissions},async listPresented(){if(!t.getPresentedNotificationsAsync)throw new Error("This notification SDK cannot list presented notifications.");let c=await ce(t.getPresentedNotificationsAsync());return e.setPresented(c),e.getSnapshot().presented},async refreshToken(c){let{type:d}=g(c);if(d==="expo"){if(!t.getExpoPushTokenAsync||!i.projectId)throw new Error("Set projectId in installExpoNotificationCapture before requesting an Expo token.");let E=await ce(t.getExpoPushTokenAsync({projectId:i.projectId}));return await e.observeToken("expo",E.data,{projectId:i.projectId}),{type:"expo",value:E.data}}if(d!=="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.");let A=await ce(t.getDevicePushTokenAsync());if(A.type!=="ios"&&A.type!=="android")throw new Error("This platform does not provide an APNs or FCM token.");return await e.observeToken(A.type==="ios"?"apns":"fcm",A.data),{type:A.type==="ios"?"apns":"fcm",value:A.data}},async scheduleLocal(c){if(!t.scheduleNotificationAsync)throw new Error("This notification SDK cannot schedule local notifications.");let{title:d,body:A,data:E,seconds:T}=g(c);if(typeof d!="string"||typeof A!="string"||typeof T!="number"||!Number.isFinite(T)||T<1||T>3600)throw new Error("Provide title, body and a delay from 1 to 3600 seconds.");if(E!==void 0&&(E===null||typeof E!="object"||Array.isArray(E)))throw new Error("Local notification data must be an object.");let J=await ce(t.scheduleNotificationAsync({content:{title:d,body:A,data:E??{}},trigger:{type:"timeInterval",seconds:T,repeats:false}}));return await e.record("local-scheduled",{title:d,body:A,data:E,seconds:T},{notificationId:J,title:d,testId:typeof g(E).__buoyTestId=="string"?g(E).__buoyTestId:null}),{notificationId:J,transport:"local"}}};return p.getPermissions().catch(()=>{}),{actions:p,ready:u,dispose(){r=true;for(let c of n)c.remove()}}}function Ro(e,t){let i=new Map;return{...t,handleNotification:async function(...o){let r=X(o[0]);r.notificationId&&i.set(r.notificationId,r),i.size>50&&i.delete(i.keys().next().value);try{let n=await t.handleNotification.apply(this,o);return e.record("presentation-decision",{notification:o[0],behavior:n},X(o[0])),n}catch(n){throw e.record("presentation-error",{notification:o[0],error:n},X(o[0])),n}},handleError:function(...o){let r=z(o[0]),n=r?i.get(r):void 0;return r&&i.delete(r),e.record("presentation-error",{source:"sdk",identifier:r,error:o[1]},n??{notificationId:r}),t.handleError?.apply(this,o)}}}function zo(e){let t=X(e),i=g(e),o=g(i.data),r=g(o.UIApplicationLaunchOptionsRemoteNotificationKey),n={};if(typeof o.dataString=="string")try{n=g(JSON.parse(o.dataString))}catch{}let l=g(o.body??i.body??r.body);return{...t,testId:t.testId??z(n.__buoyTestId)??z(l.__buoyTestId),title:t.title??z(g(i.notification).title)??z(g(g(i.aps??r.aps).alert).title)}}async function Pe(e){let t;await Promise.race([e.catch(()=>{}),new Promise(i=>{t=setTimeout(i,250)})]),t&&clearTimeout(t)}function Do(e,t){return e.configure({capabilities:[...new Set([...e.getSnapshot().capabilities,"background-task"])]}),(async function(...i){let o=g(i[0]).data??i[0],r=zo(o);await Pe(e.record("background-started",i[0],r));try{let n=await t.apply(this,i);return await Pe(e.record("background-completed",{input:i[0],result:n},r)),n}catch(n){throw await Pe(e.record("background-error",{input:i[0],error:n},r)),n}})}var re="PushNotifications",de="LocalNotifications";function ge(e){let t=g(e),i=g(t.notification??e),o=g(i.data??i.extra),r=g(o.body),n=i.id;return{notificationId:typeof n=="number"?String(n):z(n),testId:z(o.__buoyTestId)??z(r.__buoyTestId),title:z(i.title)??z(g(g(o.aps).alert).title),actionIdentifier:z(t.actionId)}}function pe(e,t=15e3){return new Promise((i,o)=>{let r=setTimeout(()=>o(new Error("The notification plugin timed out. Check permission and network settings, then retry.")),t);e.then(n=>{clearTimeout(r),i(n)},n=>{clearTimeout(r),o(n)})})}function et(e,t,i){let o=t.hasCapacitorPlugin(re),r=t.hasCapacitorPlugin(de),n=["received","responses","permissions"];o&&n.push("device-token","presented"),r&&n.push("local-scheduling"),r&&!o&&n.push("presented"),e.configure({preview:Ze(i.preview),provider:"capacitor",platform:i.platform,appId:i.appId??null,providerVersion:i.providerVersion??null,capabilities:n}),t.installCapacitorBridge(),i.appId||t.loadCapacitorAppHost?.().then(b=>{b?.bundleId&&e.configure({appId:b.bundleId})}).catch(()=>{});let l=i.platform==="ios"?"apns":"fcm",u=0,p=new Set,c=250,d=new Map,A=(b,w)=>{let m=d.get(b);if(m!==void 0&&w-m<c)return null;if(d.set(b,w),d.size>100)for(let[x,C]of d)w-C>=c&&d.delete(x);return w},E=b=>{if(b.plugin!==re&&b.plugin!==de)return;let w=b.result,m=`${b.plugin}:${b.method}:${JSON.stringify(w??null).slice(0,1500)}`;if(b.kind==="event"&&A(m,b.start)===null)return;let x=`${m}:${b.start}`;if(b.kind==="event")switch(b.method){case"registration":{let C=z(g(w).value);C&&e.observeToken(l,C).catch(()=>{});return}case"pushNotificationReceived":case"localNotificationReceived":e.record("received",w,{...ge(w),provider:"capacitor",dedupeKey:x});return;case"pushNotificationActionPerformed":case"localNotificationActionPerformed":e.record("response",w,{...ge(w),provider:"capacitor",dedupeKey:x});return;default:return}if(!(b.kind!=="promise"||b.ok!==true))if(b.method==="checkPermissions"||b.method==="requestPermissions")e.setPermissions({plugin:b.plugin,...g(w)});else if(b.plugin===de&&b.method==="schedule")for(let C of Array.isArray(b.options.notifications)?b.options.notifications:[]){let k=ge(C);e.record("local-scheduled",C,{...k,provider:"capacitor"})}else b.method==="getDeliveredNotifications"&&e.setPresented(g(w).notifications??w)},T=()=>{let b=t.getCapacitorCalls();for(let m of b)m.seq<=u||p.has(m.seq)||m.kind==="promise"&&m.end===void 0||(p.add(m.seq),E(m));let w=b[0]?.seq??0;if(w>u+1){u=w-1;for(let m of Array.from(p))m<=u&&p.delete(m)}},J=t.subscribeCapacitorCalls(T);T();let F=o?re:de,j={async getPermissions(){if(!o&&!r)throw new Error("Install @capacitor/push-notifications or @capacitor/local-notifications in the app.");let b=await pe(t.callCapacitorAsApp(F,"checkPermissions"));return e.setPermissions({plugin:F,...g(b)}),e.getSnapshot().permissions},async listPresented(){if(!o&&!r)throw new Error("This app has no notification plugin that can list presented notifications.");let b=await pe(t.callCapacitorNative(F,"getDeliveredNotifications"));return e.setPresented(g(b).notifications??b),e.getSnapshot().presented},async refreshToken(b){let{type:w}=g(b);if(w==="expo")throw new Error("Expo push tokens need expo-notifications; this app uses Capacitor.");if(w!=="device")throw new Error('Token type must be "device".');if(!o)throw new Error("Install @capacitor/push-notifications to register a device token.");let m=null,x=new Promise((C,k)=>{t.listenCapacitorNative(re,"registration",R=>{let M=z(g(R).value);M&&C(M)}).then(R=>{m=R.remove}),t.listenCapacitorNative(re,"registrationError",R=>{k(new Error(z(g(R).error)??"Push registration failed."))}).then(R=>{let M=m;m=async()=>{await M?.(),await R.remove()}})});try{await pe(t.callCapacitorNative(re,"register"));let C=await pe(x);return await e.observeToken(l,C),{type:l,value:C}}finally{m?.()}},async scheduleLocal(b){if(!r)throw new Error("Install @capacitor/local-notifications to schedule local notifications.");let{title:w,body:m,data:x,seconds:C}=g(b);if(typeof w!="string"||typeof m!="string"||typeof C!="number"||!Number.isFinite(C)||C<1||C>3600)throw new Error("Provide title, body and a delay from 1 to 3600 seconds.");if(x!==void 0&&(x===null||typeof x!="object"||Array.isArray(x)))throw new Error("Local notification data must be an object.");let k=Math.floor(Math.random()*2e9)+1,R={id:k,title:w,body:m,extra:x??{},schedule:{at:new Date(Date.now()+C*1e3).toISOString()}};return await pe(t.callCapacitorNative(de,"schedule",{notifications:[R]})),await e.record("local-scheduled",{title:w,body:m,data:x,seconds:C},{notificationId:String(k),title:w,testId:typeof g(x).__buoyTestId=="string"?g(x).__buoyTestId:null,provider:"capacitor"}),{notificationId:String(k),transport:"local"}}};return j.getPermissions().catch(()=>{}),{actions:j,ready:e.ready,dispose(){J()}}}import*as tt from"@buoy-gg/license/web";var be=globalThis;function Ee(e=false){return typeof he<"u"&&he||e===true}function Le(){return be.__buoyNotificationsV1?.recorder??null}function ot(e){let t=be.__buoyNotificationsV1;if(!t){let i=e.storage?{storage:e.storage,durable:e.durable===true}:Ao();t={recorder:new Ae({...i,enabled:()=>Ee(e.enableInRelease),appState:()=>_e.currentState??"unknown",autoStart:true})},be.__buoyNotificationsV1=t}return t}function jo(e,t={}){if(!Ee(t.enableInRelease))return null;let i=JSON.stringify([t.platform??Ie.OS,t.appId,t.providerVersion,t.projectId,t.enableInRelease,t.preview]),o=ot(t);return(o.sdk!==e||o.key!==i)&&(o.attachment?.dispose(),o.attachment=Qe(o.recorder,e,{...t,platform:t.platform??Ie.OS}),o.sdk=e,o.key=i),o.recorder}function it(e={}){let t=tt.capacitorPlatform();if(!t||!Ee(e.enableInRelease))return null;let i=JSON.stringify(["capacitor",e.appId,e.providerVersion,e.enableInRelease,e.preview]),o=ot(e);return(o.sdk!=="capacitor"||o.key!==i)&&(o.attachment?.dispose(),o.attachment=et(o.recorder,tt,{...e,platform:t}),o.sdk="capacitor",o.key=i),o.recorder}var rt=new Ae;function Y(){let e=be.__buoyNotificationsV1;if(!e)throw new Error("Install notification capture in the app entry point (installExpoNotificationCapture), before rendering the root component. Capacitor apps capture by themselves in debug builds.");return e}var ne={version:1,getSnapshot:()=>(Le()??rt).getSnapshot(),subscribe:e=>(Le()??rt).subscribe(e),actions:{getSnapshot:()=>ne.getSnapshot(),getCapabilities:()=>{let{ready:e,provider:t,providerVersion:i,platform:o,appId:r,capabilities:n,durable:l,storageError:u}=ne.getSnapshot();return{ready:e,provider:t,providerVersion:i,platform:o,appId:r,capabilities:n,durable:l,storageError:u}},getEvent(e){let{id:t}=g(e);if(typeof t!="string")throw new Error("Provide the captured event id.");return Y().recorder.getSnapshot().events.find(i=>i.id===t)??null},async setCaptureSession(e){let{runId:t,durationMs:i}=g(e);if(typeof t!="string"&&t!==null)throw new Error("Provide runId, or null to stop capture.");if(i!==void 0&&typeof i!="number")throw new Error("durationMs must be a number.");return Y().recorder.setCaptureSession(t,i)},clearCapturedEvents:()=>Y().recorder.clearCapturedEvents(),getPermissions:()=>Y().attachment.actions.getPermissions(),listPresented:()=>Y().attachment.actions.listPresented(),refreshToken:e=>Y().attachment.actions.refreshToken(e),scheduleLocal:e=>Y().attachment.actions.scheduleLocal(e)}};import{useEffect as Bo,useMemo as nt,useState as Z}from"react";import{ChevronDown as Oo,ChevronLeft as Vo,ChevronRight as at,Copy as st,ModalHeader as Re,NightBadge as me,NightCard as U,NightRows as lt,NightSectionLabel as G,NightSegmented as Ho,NotificationsIcon as Fo,PowerToggleButton as Ko,Search as Mo,Settings as Wo,ToolEmptyState as ze,Trash2 as _o,X as Jo,copyToClipboard as $o,night as D,useSafeAreaInsets as qo}from"@buoy-gg/shared-ui/web";import{DataViewer as Uo}from"@buoy-gg/shared-ui/web/dataViewer";import{useRef as Go,useState as Q}from"react";import{NightSegmented as Xo,night as ae}from"@buoy-gg/shared-ui/web";import{useEffect as Yo,useState as ct}from"react";import{CheckCircle as Zo,ChevronDown as Qo,ChevronRight as ei,NotificationsIcon as dt,XCircle as ti,night as P,useSafeAreaInsets as oi}from"@buoy-gg/shared-ui/web";import{jsx as N,jsxs as V}from"react/jsx-runtime";function pt(e){let[t,i]=ct(false);Yo(()=>i(false),[e.appearance?.iconUri]);let o=e.appearance?.textColor?{color:e.appearance.textColor}:void 0,[r,n]=ct(false),l=oi({minBottom:12});return V(y,{style:I.root,children:[N(oe,{testID:"notification-test-scroll",style:I.root,contentContainerStyle:I.scroll,keyboardShouldPersistTaps:"handled",children:V(y,{style:I.content,children:[V(y,{style:I.intro,children:[N(h,{accessibilityRole:"header",style:I.heading,children:"Test a notification"}),N(h,{style:I.caption,children:"Send a test notification to your app."})]}),e.destination,e.previewNote?N(h,{style:I.caption,children:e.previewNote}):V(y,{style:[I.preview,e.appearance?.backgroundColor?{backgroundColor:e.appearance.backgroundColor,borderColor:e.appearance.backgroundColor}:void 0],accessibilityLabel:"Notification preview",children:[V(y,{style:I.row,children:[e.appearance?.iconUri&&!t?N($e,{testID:"buoy-internal-notification-preview",source:{uri:e.appearance.iconUri},accessibilityLabel:`${e.appearance.appName??e.appName} icon`,style:I.appIcon,onError:()=>i(true)}):N(y,{style:I.iconFallback,children:N(dt,{size:22,color:P.color.accent})}),N(h,{numberOfLines:1,style:[I.caption,I.appName,o],children:e.appearance?.appName??e.appName}),N(h,{style:[I.caption,o],children:"now"})]}),N(le,{accessibilityLabel:"Notification title",placeholder:"Title",placeholderTextColor:P.color.placeholder,value:e.title,onChangeText:e.onTitleChange,style:[I.input,I.title,o],editable:!e.busy}),N(le,{accessibilityLabel:"Notification message",placeholder:"Message",placeholderTextColor:P.color.placeholder,value:e.message,onChangeText:e.onMessageChange,style:[I.input,o],editable:!e.busy})]}),e.result&&V(y,{accessibilityRole:"summary",accessibilityLiveRegion:"polite",testID:"notification-test-result",style:I.result,children:[V(y,{style:I.row,children:[e.result.failed?N(ti,{size:16,color:P.color.danger}):N(Zo,{size:16,color:P.color.accent}),N(h,{style:I.resultTitle,children:e.result.title})]}),N(h,{style:I.caption,children:e.result.message}),N(W,{accessibilityRole:"button",accessibilityLabel:"View activity",onPress:e.onViewActivity,style:I.secondary,children:N(h,{style:I.secondaryText,children:"View activity"})})]}),V(y,{children:[V(W,{accessibilityRole:"button",accessibilityLabel:"Notification options",accessibilityState:{expanded:r},onPress:()=>n(!r),style:I.options,children:[r?N(Qo,{size:12,color:P.color.textSecondary}):N(ei,{size:12,color:P.color.textSecondary}),N(h,{style:I.caption,children:"Options"})]}),r&&e.options]})]})}),V(y,{style:[I.footer,{paddingBottom:l.bottom}],children:[!!e.error&&N(h,{accessibilityRole:"alert",style:I.error,children:e.error}),!!e.notice&&N(h,{accessibilityLiveRegion:"polite",style:I.caption,children:e.notice}),V(y,{style:I.footerRow,children:[N(h,{style:[I.caption,I.hint],children:e.hint}),V(W,{accessibilityRole:"button",accessibilityLabel:e.busy?"Sending\u2026":"Send notification",accessibilityState:{disabled:e.disabled||e.busy},disabled:e.disabled||e.busy,onPress:e.onSend,style:({pressed:u})=>[I.send,(e.disabled||e.busy)&&I.disabled,u&&I.pressed],children:[N(dt,{size:15,color:P.color.onAccent}),N(h,{style:I.sendText,children:e.busy?"Sending\u2026":"Send notification"})]})]})]})]})}var I=fe.create({root:{flex:1,minHeight:0,minWidth:0},scroll:{padding:16,flexGrow:1},content:{width:"100%",maxWidth:620,alignSelf:"center",gap:20},intro:{gap:8,paddingTop:8},heading:{color:P.color.text,fontSize:22,fontWeight:"600",letterSpacing:-.5},caption:{color:P.color.textSecondary,fontSize:12,lineHeight:18},row:{flexDirection:"row",alignItems:"center",gap:8},appName:{flex:1,fontWeight:"600"},appIcon:{width:36,height:36,borderRadius:8},iconFallback:{width:36,height:36,alignItems:"center",justifyContent:"center",borderRadius:8,backgroundColor:P.color.fillSecondary},preview:{padding:16,gap:8,borderWidth:1,borderColor:P.color.glassBorder,borderRadius:20,backgroundColor:P.color.glass},input:{color:P.color.text,fontSize:14,padding:6,minHeight:36},title:{fontSize:16,fontWeight:"600"},result:{gap:10,padding:16,borderWidth:1,borderColor:P.color.glassBorder,borderRadius:14},resultTitle:{color:P.color.text,fontWeight:"500",fontSize:13,flexShrink:1},secondary:{alignSelf:"flex-start",paddingHorizontal:14,paddingVertical:8,borderRadius:24,backgroundColor:P.color.fillSecondary},secondaryText:{color:P.color.accent,fontSize:13},options:{flexDirection:"row",alignItems:"center",gap:6,paddingVertical:12},footer:{padding:14,gap:8,borderTopWidth:1,borderTopColor:P.color.separator},footerRow:{flexDirection:"row",flexWrap:"wrap",alignItems:"center",justifyContent:"space-between",gap:12},hint:{flexGrow:1,flexShrink:1,flexBasis:200},send:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:8,borderRadius:24,paddingHorizontal:18,paddingVertical:12,backgroundColor:P.color.accent},sendText:{color:P.color.onAccent,fontSize:13,fontWeight:"600"},disabled:{opacity:.4},pressed:{opacity:.8},error:{color:P.color.danger,fontSize:12,lineHeight:18}});import{jsx as _,jsxs as ve}from"react/jsx-runtime";function ii({snapshot:e,onAction:t,onViewActivity:i}){let[o,r]=Q("Test notification"),[n,l]=Q("Tap to open the app."),[u,p]=Q("{}"),[c,d]=Q("1"),[A,E]=Q(false),T=Go(false),[J,F]=Q(null),[j,b]=Q(null),w={},m=null;try{if(w=JSON.parse(u),!w||typeof w!="object"||Array.isArray(w))throw new Error}catch{m="Custom data must be a JSON object. Open Options to edit it."}async function x(){if(T.current||m)return;T.current=true,E(true),b(null),F(null);let L={testId:`buoy-local-${Date.now()}-${Math.random().toString(36).slice(2)}`,startedAt:Date.now(),appId:e?.appId??null};try{await t("setCaptureSession",{runId:L.testId,durationMs:18e5}),await t("scheduleLocal",{title:o,body:n,data:{...w,__buoyTestId:L.testId},seconds:Number(c)}),b(L)}catch(te){F(te instanceof Error?te.message:String(te))}finally{T.current=false,E(false)}}let C=j&&j.appId===e?.appId?e.events.filter(L=>L.testId===j.testId&&L.capturedAt>=j.startedAt):[],k=C.some(L=>L.kind==="received"),R=C.some(L=>L.kind==="response"||L.kind==="startup-response"),M=C.some(L=>L.kind==="app-outcome"),$=!!e?.capabilities.includes("local-scheduling");return _(pt,{title:o,message:n,onTitleChange:r,onMessageChange:l,appName:"This app",appearance:e?.preview,destination:ve(y,{style:H.destination,children:[ve(y,{style:H.field,children:[_(h,{style:H.label,children:"Device"}),_(h,{style:H.value,children:"This device"})]}),ve(y,{style:H.field,children:[_(h,{style:H.label,children:"Delivery"}),_(h,{style:H.value,children:"Local notification"})]})]}),options:ve(y,{style:H.options,children:[_(h,{style:H.label,children:"Send after"}),_(Xo,{tabs:[{key:"1",label:"1 second"},{key:"10",label:"10 seconds"}],activeKey:c,onChange:d,size:"sm",glass:true}),_(h,{style:H.label,children:"Custom data"}),_(le,{accessibilityLabel:"Notification custom data",value:u,onChangeText:p,multiline:true,autoCapitalize:"none",autoCorrect:false,style:H.json}),_(h,{style:H.label,children:"Use the delay to leave the app before delivery. Simulator push and raw APNs payloads are available on desktop."})]}),result:j?{title:M?"App reported an outcome":R?"Notification tapped":k?"Received by app":"Notification scheduled",message:R?"Open Activity to inspect the app\u2019s response.":"Tap the notification to test what opens."}:null,onViewActivity:i,onSend:()=>{x()},busy:A,disabled:!$||!!m,error:J??m,hint:$?c==="10"?"You have 10 seconds to leave the app.":"Sends locally on this device after one second.":"Connect Expo notification capture to send a local test."})}var H=fe.create({destination:{flexDirection:"row",gap:12},field:{flex:1,gap:7},label:{color:ae.color.textSecondary,fontSize:12,lineHeight:18},value:{color:ae.color.text,fontSize:13,borderWidth:1,borderColor:ae.color.glassBorder,backgroundColor:ae.color.glass,borderRadius:10,padding:11},options:{gap:12},json:{color:ae.color.text,fontSize:12,minHeight:100,textAlignVertical:"top",padding:12,borderWidth:1,borderColor:ae.color.glassBorder,borderRadius:10}});import{monoFont as ue,night as v}from"@buoy-gg/shared-ui/web";var s=fe.create({root:{flex:1,minHeight:0,backgroundColor:"transparent"},fill:{flex:1,minHeight:0},inlineHeader:{paddingHorizontal:12,paddingVertical:8,borderBottomWidth:1,borderBottomColor:v.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:v.color.textTertiary},liveDot:{backgroundColor:v.color.accent},caption:{color:v.color.textSecondary,fontSize:12,lineHeight:17},provider:{color:v.color.textSecondary,fontSize:11,marginLeft:"auto",fontFamily:ue},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:v.color.glass,borderWidth:1,borderColor:v.color.glassBorder,borderRadius:v.radius.row},searchInput:{flex:1,minWidth:0,height:"100%",color:v.color.text,fontSize:13,padding:0},clearSearch:{padding:6},iconButton:{width:34,height:34,alignItems:"center",justifyContent:"center",backgroundColor:v.color.buttonSurface,borderRadius:8,borderWidth:1,borderColor:v.color.border},event:{backgroundColor:v.color.glass,borderRadius:v.radius.input,borderWidth:1,borderColor:v.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:v.color.textSecondary,fontFamily:ue,fontSize:10},eventSubject:{flexDirection:"row",alignItems:"center",gap:8},eventTitle:{flex:1,color:v.color.text,fontSize:15,fontWeight:"500"},eventMeta:{color:v.color.textSecondary,fontFamily:ue,fontSize:10,lineHeight:15},resultCount:{color:v.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:v.radius.pill,backgroundColor:v.color.fillSecondary,alignSelf:"flex-start"},buttonText:{color:v.color.accent,fontSize:13,fontWeight:"600"},primaryButton:{backgroundColor:v.color.accent},primaryButtonText:{color:v.color.onAccent},pressed:{opacity:.7},disabled:{opacity:.4},detailTitle:{color:v.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:v.color.text,fontFamily:ue,fontSize:12,lineHeight:18},disclosure:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingHorizontal:16,paddingVertical:14},disclosureTitle:{color:v.color.text,fontSize:13,fontWeight:"500"},jsonBody:{padding:10,borderTopWidth:1,borderTopColor:v.color.separator},token:{color:v.color.text,fontFamily:ue,fontSize:12,lineHeight:20},bodyText:{color:v.color.text,fontSize:14,lineHeight:21},footnote:{color:v.color.textSecondary,fontSize:12,lineHeight:18,marginTop:8,marginHorizontal:4},emptyFootnote:{color:v.color.textSecondary,fontSize:12,lineHeight:18,textAlign:"center",marginHorizontal:28},sectionActions:{flexDirection:"row",marginBottom:10},warning:{color:v.color.warning,fontSize:12,lineHeight:18},notice:{color:v.color.accent,backgroundColor:v.color.glass,paddingHorizontal:16,paddingVertical:10,fontSize:12,lineHeight:18},errorNotice:{color:v.color.danger,backgroundColor:v.color.glass,paddingHorizontal:16,paddingVertical:10,fontSize:12,lineHeight:18},errorText:{color:v.color.danger}});import{Fragment as De,jsx as a,jsxs as f}from"react/jsx-runtime";var je={received:"App received",response:"Notification response","startup-response":"Response recovered at startup","presentation-decision":"Presentation decision","presentation-error":"Presentation error","background-started":"Background task started","background-completed":"Background task completed","background-error":"Background task failed","app-outcome":"App outcome","local-scheduled":"Local notification scheduled"};function ut(e){return e.includes("error")?"danger":e==="startup-response"?"warning":e==="received"||e==="app-outcome"?"accent":"neutral"}function K({label:e,onPress:t,disabled:i,primary:o,icon:r}){return f(W,{accessibilityRole:"button",accessibilityLabel:e,accessibilityState:{disabled:!!i},disabled:i,onPress:t,style:({pressed:n})=>[s.button,o&&s.primaryButton,n&&s.pressed,i&&s.disabled],children:[r,a(h,{style:[s.buttonText,o&&s.primaryButtonText],children:e})]})}function ee({label:e,value:t}){return f(y,{style:s.field,children:[a(h,{style:[s.caption,s.fieldLabel],children:e}),a(h,{selectable:true,style:s.value,children:t})]})}function we({title:e,value:t,initiallyOpen:i=true}){let[o,r]=Z(i),n=JSON.stringify(t??null),l=nt(()=>JSON.parse(n),[n]);return f(U,{glass:true,children:[f(W,{accessibilityRole:"button",accessibilityLabel:e,accessibilityState:{expanded:o},onPress:()=>r(u=>!u),style:s.disclosure,children:[a(h,{style:s.disclosureTitle,children:e}),o?a(Oo,{size:14,color:D.color.textSecondary}):a(at,{size:14,color:D.color.textSecondary})]}),o&&a(y,{style:s.jsonBody,children:a(Uo,{title:"",data:l,rawMode:true,initialExpanded:true,showTypeFilter:false})})]})}function ht({snapshot:e,onAction:t,sender:i,activeTab:o,onTabChange:r,renderShell:n}){let[l,u]=Z("send"),p=o??l,[c,d]=Z(""),[A,E]=Z(null),[T,J]=Z(false),[F,j]=Z(null),[,b]=Z(0),w=qo({minBottom:16}),m=e?.session?.expiresAt;Bo(()=>{if(!m||m<=Date.now())return;let S=setTimeout(()=>b(q=>q+1),m-Date.now()+1);return()=>clearTimeout(S)},[m]);let x=!!m&&m>Date.now(),C=nt(()=>(e?.events??[]).filter(S=>JSON.stringify(S).toLowerCase().includes(c.trim().toLowerCase())).slice().reverse(),[e?.events,c]),k=e?.events.find(S=>S.id===A),R=e?.events.length??0,M=!!e?.provider;function $(S){u(S),r?.(S),j(null)}async function L(S,q){if(T)return false;J(true),j(null);try{return await t(S,q),true}catch(Se){return j({text:Se instanceof Error?Se.message:String(Se),error:true}),false}finally{J(false)}}let te=()=>{L("setCaptureSession",{runId:`capture-${Date.now()}`,durationMs:18e5})},Oe=()=>{L("setCaptureSession",{runId:null})};async function Ve(S){let q=await $o(S);j({text:q?"Copied to clipboard.":"Clipboard is unavailable. Select the text to copy it.",error:!q})}let gt=[{key:"send",label:"Test"},{key:"events",label:`Activity (${R})`}],He=f(Re,{children:[a(Re.Content,{title:"",noMargin:true,children:a(Ho,{tabs:gt,activeKey:p,onChange:$,size:"sm",glass:true})}),f(Re.Actions,{children:[a(W,{accessibilityRole:"button",accessibilityLabel:"Notification settings",onPress:()=>$(p==="setup"||p==="tokens"?"send":"setup"),style:s.iconButton,children:a(Wo,{size:16,color:p==="setup"||p==="tokens"?D.color.accent:D.color.textSecondary})}),p!=="send"&&a(Ko,{isEnabled:x,onToggle:x?Oe:te,disabled:!M||T,accessibilityLabel:x?"Stop notification capture":"Start notification capture",testID:"notifications-capture"})]})]}),Fe=f(y,{style:s.root,children:[M&&p!=="send"&&f(y,{style:s.status,children:[f(y,{style:s.statusLabel,children:[a(y,{style:[s.dot,x&&s.liveDot]}),a(h,{style:s.caption,children:x?"Recording":"Capture stopped"})]}),p!=="events"&&a(h,{style:s.caption,children:e.durable?"Persistent history":"Memory only"}),p!=="events"&&f(h,{style:s.provider,children:[e.provider," \xB7 ",e.platform]})]}),e?.storageError&&f(h,{accessibilityRole:"alert",style:s.errorNotice,children:["Storage: ",e.storageError]}),F&&a(h,{accessibilityRole:F.error?"alert":"text",style:[s.notice,F.error&&s.errorText],children:F.text}),!i&&a(y,{style:p==="send"?s.fill:{display:"none"},children:a(ii,{snapshot:e,onAction:t,onViewActivity:()=>$("events")})}),p==="send"?i??null:M?f(De,{children:[p==="events"&&f(De,{children:[f(y,{style:s.searchRow,children:[f(y,{style:s.searchField,children:[a(Mo,{size:14,color:D.color.textSecondary}),a(le,{accessibilityLabel:"Filter notification events",placeholder:"Search notifications\u2026",placeholderTextColor:D.color.placeholder,value:c,onChangeText:S=>{d(S),E(null)},autoCapitalize:"none",autoCorrect:false,style:s.searchInput}),!!c&&a(W,{accessibilityRole:"button",accessibilityLabel:"Clear notification search",onPress:()=>d(""),style:s.clearSearch,children:a(Jo,{size:12,color:D.color.textSecondary})})]}),a(W,{accessibilityRole:"button",accessibilityLabel:"Clear captured events",disabled:T||!R,accessibilityState:{disabled:T||!R},style:[s.iconButton,(T||!R)&&s.disabled],onPress:()=>{L("clearCapturedEvents").then(S=>{S&&E(null)})},children:a(_o,{size:14,color:D.color.textSecondary})})]}),k?f(oe,{style:s.fill,contentContainerStyle:[s.content,{paddingBottom:w.bottom}],keyboardShouldPersistTaps:"handled",children:[f(y,{style:s.actionRow,children:[a(K,{label:"Back to events",onPress:()=>E(null),icon:a(Vo,{size:14,color:D.color.accent})}),a(K,{label:"Copy event JSON",onPress:()=>{Ve(k)},icon:a(st,{size:14,color:D.color.accent})})]}),f(U,{glass:true,padded:true,children:[a(me,{label:je[k.kind]??k.kind,tone:ut(k.kind)}),a(h,{style:s.detailTitle,children:k.title??"Notification event"}),a(h,{style:s.caption,children:new Date(k.capturedAt).toLocaleString()})]}),f(y,{children:[a(G,{children:"Observation"}),a(U,{glass:true,children:f(lt,{children:[a(ee,{label:"App state at callback",value:k.observedAppState}),k.testId&&a(ee,{label:"Test ID",value:k.testId}),k.notificationId&&a(ee,{label:"Notification ID",value:k.notificationId}),k.actionIdentifier&&a(ee,{label:"Action",value:k.actionIdentifier})]})})]}),k.kind==="startup-response"&&a(h,{style:s.footnote,children:"Recovered from the SDK cache. This alone does not establish why the app launched."}),k.truncated&&a(h,{style:s.warning,children:"This payload was truncated when captured."}),a(we,{title:"Payload",value:k.raw}),a(we,{title:"Full event",value:k,initiallyOpen:false})]}):a(Je,{data:C,keyExtractor:S=>S.id,style:s.fill,contentContainerStyle:[s.eventList,{paddingBottom:w.bottom}],keyboardShouldPersistTaps:"handled",initialNumToRender:15,ListHeaderComponent:c?f(h,{style:s.resultCount,children:[C.length," of ",R," events"]}):null,ListFooterComponent:e.evicted>0?f(h,{style:s.footnote,children:[e.evicted," older records removed by the history limit."]}):null,ListEmptyComponent:a(ze,{otto:c?"sad":x?"listening":"paused",title:c?"No matching events":x?"Waiting for notifications":"Capture is stopped",message:c?"Try another title, test ID, or payload value.":x?"Send a notification from Buoy Desktop or your app. Background alerts can reach the system tray before an app callback runs.":"Start capture with the power button, then send a notification."}),renderItem:({item:S})=>a(ri,{event:S,onPress:()=>E(S.id)})})]}),p==="tokens"&&f(oe,{style:s.fill,contentContainerStyle:[s.content,{paddingBottom:w.bottom}],keyboardShouldPersistTaps:"handled",children:[f(y,{children:[a(K,{label:"Back to settings",onPress:()=>$("setup")}),a(G,{children:"Registration"}),f(U,{glass:true,padded:true,children:[a(h,{style:s.bodyText,children:"Register a token to test delivery through your push provider."}),f(y,{style:s.actionRow,children:[a(K,{label:"Register device token",onPress:()=>{L("refreshToken",{type:"device"})},disabled:T,primary:true}),a(K,{label:"Register Expo token",onPress:()=>{L("refreshToken",{type:"expo"})},disabled:T||!e.capabilities.includes("expo-token")})]})]}),a(h,{style:s.footnote,children:"Registration runs only when you or your app request it. Simulator sends work without a token."})]}),e.tokens.length===0?a(ze,{otto:"listening",title:"No tokens observed",message:"Register a device token above, or let your app register one."}):e.tokens.map((S,q)=>f(y,{children:[a(G,{children:S.type.toUpperCase()+" token"}),f(U,{glass:true,padded:true,children:[f(y,{style:s.actionRow,children:[a(me,{label:S.type,tone:"accent"}),S.environment&&a(h,{style:s.caption,children:S.environment})]}),a(h,{selectable:true,style:s.token,children:S.value}),S.projectId&&f(h,{selectable:true,style:s.caption,children:["Project: ",S.projectId]}),f(h,{style:s.caption,children:["Observed ",new Date(S.observedAt).toLocaleString()]}),a(y,{style:s.actionRow,children:a(K,{label:"Copy "+S.type.toUpperCase()+" token",onPress:()=>{Ve(S.value)},icon:a(st,{size:14,color:D.color.accent})})})]})]},S.type+"-"+q))]}),p==="setup"&&f(oe,{style:s.fill,contentContainerStyle:[s.content,{paddingBottom:w.bottom}],keyboardShouldPersistTaps:"handled",children:[f(y,{children:[a(K,{label:"Device tokens",onPress:()=>$("tokens")}),a(G,{children:"Capture session"}),f(U,{glass:true,padded:true,children:[f(y,{style:s.actionRow,children:[a(me,{label:x?"Recording":"Stopped",tone:x?"accent":"neutral"}),a(h,{style:s.caption,children:x?"Until "+new Date(m).toLocaleTimeString():"Ready when you are"})]}),f(y,{style:s.actionRow,children:[a(K,{label:"Arm capture for 30 minutes",onPress:te,disabled:T,primary:true}),a(K,{label:"Stop capture",onPress:Oe,disabled:T||!x})]})]}),a(h,{style:s.footnote,children:e.durable?"History is saved on the app and survives app and desktop restarts.":"History is held in memory. Keep the app running to retain it."})]}),f(y,{children:[a(G,{children:"Connected app"}),a(U,{glass:true,children:f(lt,{children:[a(ee,{label:"App",value:e.appId??"Not supplied"}),a(ee,{label:"Provider",value:[e.provider,e.providerVersion].filter(Boolean).join(" ")}),a(ee,{label:"Platform",value:e.platform})]})})]}),f(y,{children:[a(G,{children:"Permissions"}),a(y,{style:s.sectionActions,children:a(K,{label:"Refresh permissions",disabled:T,onPress:()=>{L("getPermissions")}})}),a(we,{title:"Permission settings",value:e.permissions})]}),f(y,{children:[a(G,{children:"System tray"}),a(y,{style:s.sectionActions,children:a(K,{label:"Inspect system tray",disabled:T||!e.capabilities.includes("presented"),onPress:()=>{L("listPresented")}})}),a(we,{title:"Currently presented",value:e.presented}),a(h,{style:s.footnote,children:"Notifications currently in the system tray. Captured history is in Activity."})]}),f(y,{children:[a(G,{children:"Capabilities"}),a(U,{glass:true,padded:true,children:a(y,{style:s.actionRow,children:e.capabilities.map(S=>a(me,{label:S},S))})})]})]})]}):f(oe,{children:[a(ze,{otto:"paused",title:"Connect notification capture",message:"Install @buoy-gg/notifications and call installExpoNotificationCapture in the app entry point. Use an app-specific development build for remote notifications."}),a(h,{style:s.emptyFootnote,children:"The desktop sender works with any installed app. Inspection needs the capture integration."})]})]});return a(De,{children:n?n({header:He,body:Fe}):f(y,{style:s.root,children:[a(y,{style:s.inlineHeader,children:He}),Fe]})})}function ri({event:e,onPress:t}){let i=ut(e.kind),o=i==="danger"?D.color.danger:i==="warning"?D.color.warning:i==="accent"?D.color.accent:D.color.textSecondary;return f(W,{accessibilityRole:"button",accessibilityLabel:(je[e.kind]??e.kind)+": "+(e.title??e.testId??e.notificationId??"notification"),onPress:t,style:({pressed:r})=>[s.event,r&&s.pressed],children:[f(y,{style:s.eventTop,children:[f(y,{style:s.eventKind,children:[a(Fo,{size:13,color:o}),a(h,{numberOfLines:1,style:[s.eventLabel,{color:o}],children:je[e.kind]??e.kind})]}),a(h,{style:s.timestamp,children:new Date(e.capturedAt).toLocaleTimeString()})]}),f(y,{style:s.eventSubject,children:[a(h,{numberOfLines:1,style:s.eventTitle,children:e.title??e.testId??e.notificationId??"Notification event"}),a(at,{size:14,color:D.color.textTertiary})]}),f(h,{numberOfLines:1,style:s.eventMeta,children:[e.observedAppState,e.truncated?" \xB7 Truncated":""]})]})}import{useSyncExternalStore as ni}from"react";import{createToolFactory as ai,defineToolPreset as si,JsModal as li,NotificationsIcon as ci}from"@buoy-gg/shared-ui/web";import{jsx as Be}from"react/jsx-runtime";function ft(e){let t=ni(ne.subscribe,ne.getSnapshot);return Be(ht,{snapshot:t,renderShell:({header:i,body:o})=>Be(li,{...e,persistenceKey:e.persistenceKey??"buoy-notifications",variant:"night",header:{showToggleButton:true,customContent:i},enablePersistence:true,initialMode:"bottomSheet",disableScrollWrapper:true,children:o}),onAction:async(i,o)=>{let r=ne.actions[i];if(!r)throw new Error("This notification action is unavailable.");return r(o)}})}var yt=si({id:"push-notifications",name:"NOTIFICATIONS",description:"Send a test notification and inspect how the app responds",slot:"both",icon:({size:e,color:t})=>Be(ci,{size:e,color:t}),component:ft}),di=ai(yt);import{NotificationsIcon as pi}from"@buoy-gg/shared-ui/web";function ui(e){let t={...e.data,__buoyTestId:e.testId},i=e.silent?{"content-available":1}:{alert:{title:e.title,body:e.body},sound:"default"};return JSON.stringify(e.adapter==="expo"?{aps:i,body:t}:{...t,aps:i},null,2)}function hi(e){let t=[],i=[];if(typeof e!="string")return{valid:false,bytes:0,errors:["Provide the APNs payload as JSON text."],warnings:i,testId:null};let o=ie(e);o>4096&&t.push(`Payload is ${o} bytes. APNs payloads must fit in 4096 UTF-8 bytes.`);let r;try{r=JSON.parse(e)}catch{t.push("Payload is not valid JSON.")}let n=g(r);(!r||typeof r!="object"||Array.isArray(r))&&t.push("The payload must be a JSON object."),(!n.aps||typeof n.aps!="object"||Array.isArray(n.aps))&&t.push('The payload needs an "aps" object.');let l=g(n.aps);l.alert!==void 0&&typeof l.alert!="string"&&(l.alert===null||typeof l.alert!="object"||Array.isArray(l.alert))&&t.push("aps.alert must be text or an object."),l.badge!==void 0&&(!Number.isInteger(l.badge)||Number(l.badge)<0)&&t.push("aps.badge must be a non-negative integer.");for(let p of["content-available","mutable-content"])l[p]!==void 0&&l[p]!==1&&t.push(`aps.${p} must be 1 when present.`);l["content-available"]===1&&i.push("Background execution depends on app configuration and OS scheduling. A successful send does not prove the task ran."),l["mutable-content"]===1&&i.push("Use real APNs delivery to verify notification service extensions."),n.data!==void 0&&n.body===void 0&&i.push("Expo on iOS reads custom data from a top-level body object. This raw payload will be sent unchanged.");let u=g(n.body).__buoyTestId??n.__buoyTestId;return{valid:t.length===0,bytes:o,errors:t,warnings:i,testId:typeof u=="string"?u:null}}var fi=(()=>{try{return globalThis.Capacitor?.isNativePlatform?.()===true}catch{return false}})();fi&&typeof he<"u"&&he&&it();export{Ae as NotificationRecorder,pt as NotificationTestView,ht as NotificationToolView,pi as NotificationsIcon,ft as NotificationsModal,et as attachCapacitorNotifications,Qe as attachExpoNotifications,ge as capacitorMetadata,ui as composeSimulatorPayload,To as createExpoNotificationStorage,di as createNotificationTool,X as expoMetadata,Le as getNotificationRecorder,it as installCapacitorNotificationCapture,jo as installExpoNotificationCapture,Ro as instrumentExpoNotificationHandler,Do as instrumentNotificationBackgroundTask,ne as notificationSyncAdapter,yt as notificationToolPreset,hi as validateSimulatorPayload};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buoy-gg/notifications",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.65",
|
|
4
4
|
"description": "Send simulator notifications and inspect app receipt, interactions and device tokens.",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
"./lib/web/**/*.mjs"
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@buoy-gg/shared-ui": "^7.0.
|
|
20
|
+
"@buoy-gg/shared-ui": "^7.0.65"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
|
-
"@buoy-gg/license": "7.0.
|
|
23
|
+
"@buoy-gg/license": "7.0.65",
|
|
24
24
|
"react": "*",
|
|
25
25
|
"react-native": "*"
|
|
26
26
|
},
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@types/react": "^19.1.0",
|
|
29
29
|
"@types/react-native": "^0.73.0",
|
|
30
30
|
"typescript": "~5.8.3",
|
|
31
|
-
"@buoy-gg/license": "^7.0.
|
|
31
|
+
"@buoy-gg/license": "^7.0.65"
|
|
32
32
|
},
|
|
33
33
|
"react-native-builder-bob": {
|
|
34
34
|
"source": "src",
|