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