{"_id":"xtremepush-expo-plugin","_rev":"30-40392518e86d1b53f7c6f9ce9f5d405f","name":"xtremepush-expo-plugin","dist-tags":{"canary":"1.2.1-canary.0","rc":"1.2.9-rc","latest":"1.3.5"},"versions":{"1.0.0-beta.1":{"name":"xtremepush-expo-plugin","version":"1.0.0-beta.1","keywords":["expo","xtremepush","plugin","react-native"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.0.0-beta.1","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://github.com/xtremepush/Xtremepush-Expo","bugs":{"url":"https://github.com/xtremepush/Xtremepush-Expo/issues"},"dist":{"shasum":"dcc994c57f33ce39fe4f6fac33d995de603f2efe","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.0.0-beta.1.tgz","fileCount":8,"integrity":"sha512-zaaPPz5sHPhIEUZrYjMhn6ods+yY97ZdtM37PD9dydwnjkCiMHR8OvVmOzczLWTklTYvs+/ejMJiHjOd9zNZIA==","signatures":[{"sig":"MEQCIEd83X3THdFezMAc2TYVUNHc/DIKg6MQo9LNyRhdamwNAiBO+okIdVnESg4ciu5bg074m0DLTtZSQl/he0JbfHgJIA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":50439},"expo":{"name":"xtremepush-expo-plugin","platforms":["ios","android"]},"main":"plugins/expo-plugin.js","engines":{"node":">=16.0.0"},"scripts":{"test":"./test-plugin-e2e.sh","build":"tsc"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/Xtremepush-Expo.git","type":"git"},"_npmVersion":"11.4.2","description":"Xtremepush Expo Plugin","directories":{},"_nodeVersion":"23.11.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^4.9.0","@expo/config-plugins":"^8.0.11"},"peerDependencies":{"expo":">=53.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.0.0-beta.1_1753131481602_0.6921299329031274","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"xtremepush-expo-plugin","version":"1.0.0","keywords":["expo","config-plugin","xtremepush","push-notifications"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.0.0","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"dist":{"shasum":"b4ad464d55e613559f1c6515fa775beedad57b8f","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.0.0.tgz","fileCount":8,"integrity":"sha512-vFSbnMyKlS6UznwCrGl4Yp8OgtaD7ZFLPDeo/tPg33bI9hNQWfwcEcd0UB0x5Uo1u4isaM/057Dh6SXDWugepQ==","signatures":[{"sig":"MEYCIQCIueiZ8fTztIgQjGL1zRcSdgl78j2fgBO4Vq/wV/XmnAIhANX+Xedk+i7dskL+xTg76jZTiAL11EdNhBLWZz5tpqtx","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":44891},"main":"plugins/expo-plugin.js","scripts":{"test":"./test-plugin-e2e.sh"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"_npmVersion":"11.4.2","description":"Xtremepush Expo Config Plugin","directories":{},"_nodeVersion":"23.11.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.0.0_1754606027462_0.3221165870709488","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"xtremepush-expo-plugin","version":"1.0.1","keywords":["expo","config-plugin","xtremepush","push-notifications"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.0.1","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"dist":{"shasum":"96ec36ec6270bcf4f604e3a42657ce04eb7e4678","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.0.1.tgz","fileCount":8,"integrity":"sha512-TOvSAdcykhybJnuy7LsE0cxiPE1OMDpkYtO7jRL0I5WAH0NKYxRIqCffle2mGzyk35pq+i+EFJ0YtoS6TDbo0w==","signatures":[{"sig":"MEUCIQC8LPNDcVBNo5NL4pAQR4S1YRg51IUl203/FgUPPjnqvwIgG79t7/HcBYfTN4W3VDy4WXZs4wXhaJQ9BopcLOusOs0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":44891},"main":"plugins/expo-plugin.js","scripts":{"test":"./test-plugin-e2e.sh"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"_npmVersion":"11.4.2","description":"Xtremepush Expo Config Plugin","directories":{},"_nodeVersion":"23.11.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.0.1_1754606085500_0.37778357998017764","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"xtremepush-expo-plugin","version":"1.0.2","keywords":["expo","config-plugin","xtremepush","push-notifications"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.0.2","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"dist":{"shasum":"f7d2794c00d640edc1833f4dc9a78d4a061bf2e9","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.0.2.tgz","fileCount":8,"integrity":"sha512-RR/ZX+oOy0N1SnikIlzkHcCtkwmKhk0tH4bWyPj7nO+yCW5XLgJpjHWtCVjuL0sG6JH903S9y0J3EHHXlKDXsA==","signatures":[{"sig":"MEUCIQDmdSQ31adsPRUeAOVP40j04sMvVkIlxJtEDw1Eqjt0LQIgGcS4TlVE7jr8HTaeKfHPRc0Nb4NKln2VCfkj7XCxMbc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":45036},"main":"plugins/expo-plugin.js","gitHead":"3c5e4e6901f603893dfdfbb7bb7fb5f6453aab44","scripts":{"test":"./test-plugin-e2e.sh"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"_npmVersion":"11.4.2","description":"Xtremepush Expo Config Plugin","directories":{},"_nodeVersion":"23.11.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.0.2_1754608740283_0.9229516511275067","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"xtremepush-expo-plugin","version":"1.0.3","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.0.3","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"dist":{"shasum":"82eca615f360760c1e1b4a3d74df78a4581eb974","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.0.3.tgz","fileCount":15,"integrity":"sha512-OTRXrGkLKAp35iMItkIFu9uocfmpZOnwwJnXtVevYG3WdmFXNVNOf6VyyUk8Ew836Nvcvk1sMWk3gJrUuHjTnA==","signatures":[{"sig":"MEQCID9urixRC4d72xWpxKumoHUX+/58bwGQDsVZRu5Yly5EAiBQIn0Lmw0C0UCaKugnnVsKp/2pjgBoapd8GkxcKumk6Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":49535},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","engines":{"node":">=18.0.0"},"gitHead":"464c27468fb599b702f31ff9c4b66af3f65bfd41","scripts":{"test":"./test-plugin-e2e.sh","build":"echo 'Plugin is ready for distribution'","prepare":"echo 'XtremePush Expo Plugin'","validate":"node test-plugin-config.js"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.4.2","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"23.11.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0"},"peerDependencies":{"expo":">=47.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.0.3_1755667777167_0.41312912407244995","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"xtremepush-expo-plugin","version":"1.0.4","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.0.4","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"dist":{"shasum":"67753877f7f7641e7647be3857da24e124099ae4","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.0.4.tgz","fileCount":16,"integrity":"sha512-H+RKF/M3P8biOx4qLqJVDGNWs7XVNtFHtnrbfnhr2xxQSRo8eKBQRwECRBDU4/lYS3GuBI4zTEP2W/LeDqGraQ==","signatures":[{"sig":"MEQCIH1TNs3Wqw97g/o67tEIU2IdjtiQpzMrpWTXTWI0oX3KAiABzc3oZq9OWDuYicebg9DEk4rfC7Jbj4x0yfwYfRfCEA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":61815},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","engines":{"node":">=18.0.0"},"gitHead":"464c27468fb599b702f31ff9c4b66af3f65bfd41","scripts":{"test":"./test-plugin-e2e.sh","build":"echo 'Plugin is ready for distribution'","prepare":"echo 'XtremePush Expo Plugin'","validate":"node test-plugin-config.js"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.4.2","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"23.11.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0"},"peerDependencies":{"expo":">=47.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.0.4_1755668304890_0.31773700013250883","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"xtremepush-expo-plugin","version":"1.1.0","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.1.0","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"dist":{"shasum":"61f4b4a731c7b687cd660e9b80b397ce29d8850c","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.1.0.tgz","fileCount":17,"integrity":"sha512-/e6hDPeJKFR1AM9KKTlOmrhSWxekWquVWy2RyN53jKjW1/rNpmNmGE4QF4iUEAJlt+2wuVbGJ6KxBkQv8EQw8Q==","signatures":[{"sig":"MEUCIQD4LOvmj+6W2LR6JaVPFQmRJ1p3FtrYAv3vviUXnx6XIwIgJsdjXyYNVp6DIRyi9VZDJMwUOaTJH0v+6+0H8o0x44Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":110270},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","engines":{"node":">=18.0.0"},"gitHead":"9f60b69f0c7aa1fae17ca25474d4d11200d90d75","scripts":{"test":"./test-plugin-e2e.sh"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.4.2","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"23.11.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0"},"peerDependencies":{"expo":">=47.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.1.0_1757640024866_0.03128385691832736","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"xtremepush-expo-plugin","version":"1.1.1","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.1.1","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"dist":{"shasum":"ecf96e747d2bd8d48ec53c285e16a60ac6365500","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.1.1.tgz","fileCount":17,"integrity":"sha512-oMVyZNT5+zPeRWSIzT+eDOaUfWUtiL+VB8nWETMGE6HtmtU4XF0OsRn3PqpQ7FgD5apQbNTlqqrK7FeeYpDJPg==","signatures":[{"sig":"MEUCIGHObDC7K9I572ORPUCrGzgCOKm8coMlyGvE3dIgEs1mAiEAkNNt2JdrjwhpPsw3o9HZt+6MBMvng6O1cT4ZrGpxaFk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":118526},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","engines":{"node":">=18.0.0"},"gitHead":"a13e04a421950c3f600f1146216d1e10002b8424","scripts":{"test":"./test-plugin-e2e.sh"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.4.2","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"23.11.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0"},"peerDependencies":{"expo":">=47.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.1.1_1764803755154_0.49361231390332083","host":"s3://npm-registry-packages-npm-production"}},"1.1.2":{"name":"xtremepush-expo-plugin","version":"1.1.2","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.1.2","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"dist":{"shasum":"28ee409ff67c5daa82304cc5bed5b3e0c60a8ef4","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.1.2.tgz","fileCount":17,"integrity":"sha512-vHUlnQu6npjkWVIWkgB7VW/vaThNHC/D/xKG37D3777/W5SaM/1sSXSkz1k7dPMnu/iwM/RlyRJQoObLqW6bcg==","signatures":[{"sig":"MEUCIQCrQ9wKtBeST0nCxOftZuNPd+YKNYH8cxrjLWteNWqyZQIgZ7vSeO0uB8CJ3sHUVJ6qYYoB/AFqpGrxFjyPDtF7hU4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":119620},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","engines":{"node":">=18.0.0"},"gitHead":"890cf12386b17c7bdbec89a51f3f008ad947d73f","scripts":{"test":"./test-plugin-e2e.sh"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.7.0","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"25.4.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0"},"peerDependencies":{"expo":">=47.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.1.2_1770325029913_0.3078709967036999","host":"s3://npm-registry-packages-npm-production"}},"1.1.3":{"name":"xtremepush-expo-plugin","version":"1.1.3","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.1.3","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"dist":{"shasum":"3f88b613d4e0a76be5779651a88247d965b55b1d","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.1.3.tgz","fileCount":17,"integrity":"sha512-OUphbgCz5z+WVolQW6sahcSgIGEZgZ7W8m7wVFPYuXwzgP7PzvFF/blNYet33YImcxFzNmSBuYsaHLSIczsHUw==","signatures":[{"sig":"MEQCIAZS1CT82CqMtThAhYC2+vyr2UQYc6Tk4D00vy5imN4GAiBdP07FJwfAsgeyF3IixRWUVTUENai2ArYygnAH4OJz9w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":151564},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","engines":{"node":">=18.0.0"},"gitHead":"a13e04a421950c3f600f1146216d1e10002b8424","scripts":{"test":"./test-plugin-e2e.sh"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.10.1","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"25.7.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0"},"peerDependencies":{"expo":">=47.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.1.3_1772668488218_0.2500115498341111","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"xtremepush-expo-plugin","version":"1.2.0","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.2.0","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"dist":{"shasum":"d480df719f71c6db7e4e85a7976abad392e09562","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.2.0.tgz","fileCount":17,"integrity":"sha512-Oz6i/VvDKU8SAZfQX0zaqVlBSjVTHSvmlsYhqmSTNZXDy6DACmWULg/6bKxrHnPTGA6dPrVsOA0Q9eU8e3EdFg==","signatures":[{"sig":"MEUCIDb+jW2aAFsb140aldRMRIzknxztxc6QVqmKcjww09gnAiEA9MERTDsKGz67DTE9RuXRrmqib92US4pf8g8YbC94i7w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":150937},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","engines":{"node":">=18.0.0"},"gitHead":"eb7181bfe56f9bb019498e2eef22494ad2a4bb15","scripts":{"test":"./test-plugin-e2e.sh"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.10.1","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"25.7.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0"},"peerDependencies":{"expo":">=47.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.2.0_1773703109447_0.715109057112481","host":"s3://npm-registry-packages-npm-production"}},"1.2.1-canary.0":{"name":"xtremepush-expo-plugin","version":"1.2.1-canary.0","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.2.1-canary.0","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"dist":{"shasum":"f6b7f778cc6a50518b69f97a4a40a4a6dee94cd9","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.2.1-canary.0.tgz","fileCount":17,"integrity":"sha512-W9FYfBt2VsIImhIXpFx3JviFA43wN9ab3KP+faB/bJiEZQ7NjCNL8RLjuekL7YCRs1YRmmE509GB7e3ceNhLyA==","signatures":[{"sig":"MEUCIQCTMoB5Riz6wveyv/MHIy3yNRQEF/PZAEY2E0AK6RxFzgIgQUZj5nL6OugJL6tI7lBM1KI7rD7aCuexkfbvblUHNa8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":173354},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","engines":{"node":">=18.0.0"},"gitHead":"eb7181bfe56f9bb019498e2eef22494ad2a4bb15","scripts":{"test":"./test-plugin-e2e.sh"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.10.1","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"25.7.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"expo":"^53.0.0"},"peerDependencies":{"expo":">=47.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.2.1-canary.0_1773704472604_0.5136302946656515","host":"s3://npm-registry-packages-npm-production"}},"1.2.2":{"name":"xtremepush-expo-plugin","version":"1.2.2","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.2.2","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"dist":{"shasum":"3d9508c056874c4e031cde8e95b60c0b896b7cab","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.2.2.tgz","fileCount":18,"integrity":"sha512-mId97A6fz6gwwq136EWmQIcYKNDrdh61RBCEeBMwIKE+C4XjJBEguAmqeuvHuSvgoDZEv3pJo8fRhQ/6/4n6EQ==","signatures":[{"sig":"MEQCIE2ROlEbJpKsJOy+Fv8TmjE+WYlYxVjVq2wF5eakjyA3AiBDjOQySn5vVTIs0Ir+bjDI5S9CCQhGVYBqcwriZWsY4g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":183620},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","types":"types/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"dd10ea4bc27fa999beca7359a3875724226bc2fd","scripts":{"test":"./test-plugin-e2e.sh"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.12.0","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"25.7.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"typesVersions":{"*":{"plugins/xtremepush":["plugins/xtremepush.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0"},"peerDependencies":{"expo":">=47.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.2.2_1774393734254_0.7473765253223801","host":"s3://npm-registry-packages-npm-production"}},"1.2.3-rc.1":{"name":"xtremepush-expo-plugin","version":"1.2.3-rc.1","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.2.3-rc.1","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"dist":{"shasum":"501cae671ee2eb3782f6fae035fd0bfaf022469b","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.2.3-rc.1.tgz","fileCount":18,"integrity":"sha512-kLbvTG35yHbKZouQ+KZ0JYYR3qalAWjJ60EaHrYrRS3+u6WW2radNxpVzVArvMOmnU/WznAtuVwBAEf+HgOnuQ==","signatures":[{"sig":"MEYCIQDBIbYCnidslOYDxK4KA9rzY/yQ5zL3/BlZVLgYsAo4kwIhAKrbrep0DgJWbt4Vhnm+aiNyoWpN8XO9YJ5GNjWK1tme","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":189046},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","types":"types/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":"./plugins/expo-plugin.js","./plugins/xtremepush":{"types":"./plugins/xtremepush.d.ts","default":"./plugins/xtremepush.js"}},"gitHead":"dd10ea4bc27fa999beca7359a3875724226bc2fd","scripts":{"test":"./test-plugin-e2e.sh"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.12.0","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"25.7.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"typesVersions":{"*":{"plugins/xtremepush":["plugins/xtremepush.d.ts"]}},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"expo":"^53.0.0"},"peerDependencies":{"expo":">=51.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.2.3-rc.1_1775127596063_0.07371959565572683","host":"s3://npm-registry-packages-npm-production"}},"1.2.3":{"name":"xtremepush-expo-plugin","version":"1.2.3","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.2.3","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"dist":{"shasum":"0b2216282c159bdd3431e660be18358091f8ae4f","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.2.3.tgz","fileCount":19,"integrity":"sha512-5L3bEvpJl0uFp1dpxYavPE9z/kMmUuqjiDlEYB+6x2LpkCiCOCm8h4eqTtUEganNHozA8RCzpKbljDmnnvxJKg==","signatures":[{"sig":"MEQCIC8glzwnjx65136oxEj73FSckiLzO+PavnMwCXhaSyv9AiA0RpLuQZuYIzv6HBOY94z8/9m6qjlrShINmw+Y+oJbOw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":193000},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","types":"types/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":"./plugins/expo-plugin.js","./plugins/xtremepush":{"types":"./plugins/xtremepush.d.ts","default":"./plugins/xtremepush.js"}},"gitHead":"dd10ea4bc27fa999beca7359a3875724226bc2fd","scripts":{"test":"./test-plugin-e2e.sh"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.12.0","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"25.7.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"typesVersions":{"*":{"plugins/xtremepush":["plugins/xtremepush.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0"},"peerDependencies":{"expo":">=51.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.2.3_1775161384566_0.9680183132685938","host":"s3://npm-registry-packages-npm-production"}},"1.2.4":{"name":"xtremepush-expo-plugin","version":"1.2.4","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.2.4","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"dist":{"shasum":"d96b18392f27dc1d22d09aed3635bab195ed5a7a","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.2.4.tgz","fileCount":25,"integrity":"sha512-eDlSngMPj+8ulyfIZj36iDF4hCc94pLAOxlE58NcoX6GSny/uW2GlvR7EBE7OHmtxpOWGlcGbp+k8b0Hke8Wfg==","signatures":[{"sig":"MEUCIQCVhAKQcMZ/VXyHrPJIzvy9WrDXWzRuNuoeLef+N0XVqgIgFj9u1Fr7CpU2XxLHwuKGngnukWmaZz+SoOP7TjBme2k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":229379},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","types":"types/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":"./plugins/expo-plugin.js","./plugins/xtremepush":{"types":"./plugins/xtremepush.d.ts","default":"./plugins/xtremepush.js"}},"gitHead":"4fce1dabdc4c1eece6a3299c8a90b8a179347fbc","scripts":{"test":"node --test plugins/__tests__/unit/*.test.js plugins/__tests__/integration/*.test.js"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.12.0","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"25.7.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"typesVersions":{"*":{"plugins/xtremepush":["plugins/xtremepush.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0"},"peerDependencies":{"expo":">=51.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.2.4_1776730496479_0.49951517045399574","host":"s3://npm-registry-packages-npm-production"}},"1.2.5":{"name":"xtremepush-expo-plugin","version":"1.2.5","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.2.5","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"dist":{"shasum":"5476ccd44afaac2a44094d37ff52c227dcb0f7ea","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.2.5.tgz","fileCount":25,"integrity":"sha512-SAqBa9Y6suE4egEecE/dcBufWe9ztnXAo5ynGNkrm6pP4aRZhrseURgFj5KIiC5bNhgB9xesrAaF/isMF18i7w==","signatures":[{"sig":"MEQCIFA8EzS9i3UpAdFzXt0hXaCLqM4D1hbHEoBpas1KIATmAiBEouP1cnxfV72hw39dqw8iO4McokxLnh3I5bAd3mBQ8Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":234476},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","types":"types/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":"./plugins/expo-plugin.js","./plugins/xtremepush":{"types":"./plugins/xtremepush.d.ts","default":"./plugins/xtremepush.js"}},"gitHead":"4fce1dabdc4c1eece6a3299c8a90b8a179347fbc","scripts":{"test":"node --test plugins/__tests__/unit/*.test.js plugins/__tests__/integration/*.test.js"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.12.0","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"25.7.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"typesVersions":{"*":{"plugins/xtremepush":["plugins/xtremepush.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0"},"peerDependencies":{"expo":">=51.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.2.5_1776897244138_0.8990852969500491","host":"s3://npm-registry-packages-npm-production"}},"1.2.6":{"name":"xtremepush-expo-plugin","version":"1.2.6","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.2.6","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"dist":{"shasum":"5fe79d8f5d24c185dda382092c10f480ddc908a0","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.2.6.tgz","fileCount":25,"integrity":"sha512-cPOzkoDyXHy+0nZ2U+72uwQEf720OxyqI9rlBZAHFC+7Xj08hCqQScrjU6ysebTdVBj2Fefio0Gvgzo+uF85Fg==","signatures":[{"sig":"MEUCIGsh95F4Tn5fUoNZcknMKkmU+WIIsVL//CU3FNLtfiD4AiEApQXPx9HJbLkgC4PZoRUDV5cCgwwSXCZTBDovwO+PoXY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":247656},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","types":"types/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":"./plugins/expo-plugin.js","./plugins/xtremepush":{"types":"./plugins/xtremepush.d.ts","default":"./plugins/xtremepush.js"}},"gitHead":"b6ba83857042c12a5bce149e1466b1df126f773f","scripts":{"test":"node --test plugins/__tests__/unit/*.test.js plugins/__tests__/integration/*.test.js"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.12.0","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"25.7.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"typesVersions":{"*":{"plugins/xtremepush":["plugins/xtremepush.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0"},"peerDependencies":{"expo":">=51.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.2.6_1777580924343_0.38852741844485017","host":"s3://npm-registry-packages-npm-production"}},"1.2.7":{"name":"xtremepush-expo-plugin","version":"1.2.7","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.2.7","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"dist":{"shasum":"78f6b4e307217639236fd7ae8f2b28c157805e20","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.2.7.tgz","fileCount":26,"integrity":"sha512-x02qhcWYjPgN0XZ7ony54iqDEAQ3+pFqEcDKwfCv08lua/wn6cKbEO0+XDnUZzjpKsfGgTRWGLvsugZo4GK5mQ==","signatures":[{"sig":"MEUCICGhwvBgCatbHs/hoeFsFPm8sxvLSrIXBl/OJCRmcLdwAiEAuRbgsiK6P8087UElKgv7ZKglMzP7HV5Ibnk6ktu3kuQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":297280},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","types":"types/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":"./plugins/expo-plugin.js","./plugins/xtremepush":{"types":"./plugins/xtremepush.d.ts","default":"./plugins/xtremepush.js"}},"gitHead":"60539062f363492ed177cbff06d5b940ea0ae49d","scripts":{"lint":"node scripts/lint-package.js","test":"node scripts/run-node-tests.js","test:api":"node scripts/run-node-tests.js tests/js-api","typecheck":"node scripts/run-typecheck.js","test:config":"node scripts/run-node-tests.js plugins/__tests__/unit plugins/__tests__/integration tests/config-plugin","test:package":"node scripts/check-package-integrity.js","test:regression":"node scripts/run-node-tests.js tests/regression","example:prebuild":"node scripts/run-example-prebuild.js example","validate:release":"node scripts/validate-release.js","validate:ios:local":"node scripts/local-ios-smoke.js example","example:assert-config":"node scripts/assert-example-config.js example","validate:android:local":"node scripts/local-android-smoke.js example","example:assert-prebuild":"node scripts/assert-example-prebuild.js example"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.12.1","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"25.9.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"typesVersions":{"*":{"plugins/xtremepush":["plugins/xtremepush.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0","typescript":"^5.8.3"},"peerDependencies":{"expo":">=51.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.2.7_1778413896755_0.2190346599988624","host":"s3://npm-registry-packages-npm-production"}},"1.2.8":{"name":"xtremepush-expo-plugin","version":"1.2.8","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.2.8","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"dist":{"shasum":"517314d028fee989cbbf745a413b172734bef8cb","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.2.8.tgz","fileCount":26,"integrity":"sha512-ZGFqj6NltElf5ojbnLrKVjhPgeWi6kPTwpZ+QNZrNeKpmNmVDKbDuWMX6ImmnZdRUa+DrJ0OezCQDlyEHaH8fg==","signatures":[{"sig":"MEUCIBioigwOz9G8z3dyj/N5X+tfMvs0XPDY0139+F6K1nuKAiEAl3ImIDe3S45A5QQHWMp/bUzV3N+FrBGcadpEFFyx/0o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":317074},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","types":"types/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":"./plugins/expo-plugin.js","./plugins/xtremepush":{"types":"./plugins/xtremepush.d.ts","default":"./plugins/xtremepush.js"}},"gitHead":"91b4c4e6435fd1013c5c56f3f1665ae686117a96","scripts":{"lint":"node scripts/lint-package.js","test":"node scripts/run-node-tests.js","test:api":"node scripts/run-node-tests.js tests/js-api","typecheck":"node scripts/run-typecheck.js","test:config":"node scripts/run-node-tests.js plugins/__tests__/unit plugins/__tests__/integration tests/config-plugin","test:package":"node scripts/check-package-integrity.js","test:regression":"node scripts/run-node-tests.js tests/regression","example:prebuild":"node scripts/run-example-prebuild.js example","validate:release":"node scripts/validate-release.js","validate:ios:local":"node scripts/local-ios-smoke.js example","example:assert-config":"node scripts/assert-example-config.js example","validate:android:local":"node scripts/local-android-smoke.js example","example:assert-prebuild":"node scripts/assert-example-prebuild.js example"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.12.1","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"26.0.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"typesVersions":{"*":{"plugins/xtremepush":["plugins/xtremepush.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0","typescript":"^5.8.3"},"peerDependencies":{"expo":">=51.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.2.8_1778722517309_0.6526862814585905","host":"s3://npm-registry-packages-npm-production"}},"1.2.9-rc":{"name":"xtremepush-expo-plugin","version":"1.2.9-rc","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.2.9-rc","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"bin":{"xtremepush-verify-build":"scripts/verify-build.js"},"dist":{"shasum":"49169a90888d6a8cac23b8c28070090d9422c717","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.2.9-rc.tgz","fileCount":28,"integrity":"sha512-/UQIgZ2rao04qHt+efLsyUTPdHzyZutj2DGPDybxKjNfzRJmtyEx60iNv0E/sOC1/cvlDo6lI/WvmKQvH+Sc5Q==","signatures":[{"sig":"MEQCIBPcr2RkaHCFYtlieCGnADWk7EVoxAP6+WHq/ZlZ1/E1AiBdBJYQHOyG2INzHfvq+qf8TxuQqYrc3z/YMG/yORChIQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":379866},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","types":"types/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":"./plugins/expo-plugin.js","./plugins/xtremepush":{"types":"./plugins/xtremepush.d.ts","default":"./plugins/xtremepush.js"}},"gitHead":"50908202b84f32b4238ab48d46eb4fde6821e7e7","scripts":{"lint":"node scripts/lint-package.js","test":"node scripts/run-node-tests.js","test:api":"node scripts/run-node-tests.js tests/js-api","typecheck":"node scripts/run-typecheck.js","test:config":"node scripts/run-node-tests.js plugins/__tests__/unit plugins/__tests__/integration tests/config-plugin","test:package":"node scripts/check-package-integrity.js","test:regression":"node scripts/run-node-tests.js tests/regression","example:prebuild":"node scripts/run-example-prebuild.js example","validate:release":"node scripts/validate-release.js","validate:ios:local":"node scripts/local-ios-smoke.js example","example:assert-config":"node scripts/assert-example-config.js example","validate:android:local":"node scripts/local-android-smoke.js example","example:assert-prebuild":"node scripts/assert-example-prebuild.js example"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.12.1","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"26.0.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"typesVersions":{"*":{"plugins/xtremepush":["plugins/xtremepush.d.ts"]}},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"expo":"^53.0.0","typescript":"^5.8.3"},"peerDependencies":{"expo":">=51.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.2.9-rc_1779048222690_0.34617651967570695","host":"s3://npm-registry-packages-npm-production"}},"1.2.9":{"name":"xtremepush-expo-plugin","version":"1.2.9","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.2.9","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"bin":{"xtremepush-verify-build":"scripts/verify-build.js"},"dist":{"shasum":"d4d6ec300310e41e3e7a481e09687406e149f7a5","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.2.9.tgz","fileCount":28,"integrity":"sha512-ZkSaL0ZqtwIQ/bVFTOWM7vCPuvFGhfef1dLwntgHtudZKhAvFfDv+xzLc/+kmfHDdn5R6J67dIBoUL8CO4xxKQ==","signatures":[{"sig":"MEUCIQDK6jEBSnyI1eL64H8wEsqc6AIM4orExUkDdopaFCMH4AIgUaJrBuuKTK3AUAJLTZRkn9RtQKMXCqG49vA2VxJGBrg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":337434},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","types":"types/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":"./plugins/expo-plugin.js","./plugins/xtremepush":{"types":"./plugins/xtremepush.d.ts","default":"./plugins/xtremepush.js"}},"gitHead":"50908202b84f32b4238ab48d46eb4fde6821e7e7","scripts":{"lint":"node scripts/lint-package.js","test":"node scripts/run-node-tests.js","test:api":"node scripts/run-node-tests.js tests/js-api","typecheck":"node scripts/run-typecheck.js","test:config":"node scripts/run-node-tests.js plugins/__tests__/unit plugins/__tests__/integration tests/config-plugin","test:package":"node scripts/check-package-integrity.js","test:regression":"node scripts/run-node-tests.js tests/regression","example:prebuild":"node scripts/run-example-prebuild.js example","validate:release":"node scripts/validate-release.js","validate:ios:local":"node scripts/local-ios-smoke.js example","example:assert-config":"node scripts/assert-example-config.js example","validate:android:local":"node scripts/local-android-smoke.js example","example:assert-prebuild":"node scripts/assert-example-prebuild.js example"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.12.1","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"26.0.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"typesVersions":{"*":{"plugins/xtremepush":["plugins/xtremepush.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0","typescript":"^5.8.3"},"peerDependencies":{"expo":">=51.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.2.9_1779064737633_0.3795604627476832","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"xtremepush-expo-plugin","version":"1.3.0","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.3.0","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"bin":{"xtremepush-verify-build":"scripts/verify-build.js"},"dist":{"shasum":"637b1f5a58dd4e2e807fc8cfff652e9d428d773a","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.3.0.tgz","fileCount":28,"integrity":"sha512-AMdwFAirIC6U9D3McIBL8+nAiF7BW4bkAaxw4AQI1a0pAoJ2o3a44+GYL7gxbIbnNuUZcdWa04kevh0VucmdCQ==","signatures":[{"sig":"MEUCIHNGoFKvOTNRrHmEm/Ud3WR0btGF5xarmzZna/mVPqfwAiEAmZ7CygiArpVFAJSQmDHozyCPMq75j3Yjz+vIf1Kj70I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":371336},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","types":"types/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":"./plugins/expo-plugin.js","./plugins/xtremepush":{"types":"./plugins/xtremepush.d.ts","default":"./plugins/xtremepush.js"}},"gitHead":"29b0ff88fdffd76184e59cf0e55255fabf3bb0f8","scripts":{"lint":"node scripts/lint-package.js","test":"node scripts/run-node-tests.js","test:api":"node scripts/run-node-tests.js tests/js-api","typecheck":"node scripts/run-typecheck.js","test:config":"node scripts/run-node-tests.js plugins/__tests__/unit plugins/__tests__/integration tests/config-plugin","test:package":"node scripts/check-package-integrity.js","test:regression":"node scripts/run-node-tests.js tests/regression","example:prebuild":"node scripts/run-example-prebuild.js example","validate:release":"node scripts/validate-release.js","validate:ios:local":"node scripts/local-ios-smoke.js example","example:assert-config":"node scripts/assert-example-config.js example","validate:android:local":"node scripts/local-android-smoke.js example","example:assert-prebuild":"node scripts/assert-example-prebuild.js example"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.12.1","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"26.0.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"typesVersions":{"*":{"plugins/xtremepush":["plugins/xtremepush.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0","typescript":"^5.8.3"},"peerDependencies":{"expo":">=51.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.3.0_1780339889888_0.4550268295609199","host":"s3://npm-registry-packages-npm-production"}},"1.3.1":{"name":"xtremepush-expo-plugin","version":"1.3.1","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.3.1","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"bin":{"xtremepush-verify-build":"scripts/verify-build.js"},"dist":{"shasum":"dda894006783bffac97bcc3d082f78cd03d8eb68","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.3.1.tgz","fileCount":28,"integrity":"sha512-BaZDamle9JZDs/QdSrTfegURO1PG7IrN4M6WClhbmOPt3fvSnkLSLkRstodLM1kqmqpubQarHA56uXpARw6VgQ==","signatures":[{"sig":"MEYCIQCLmwYutHogqGZZ5kPZWZ18hWguUfKZ3M/ZjbOLraybbwIhANnHaFXvJHVKqs0lekZww08FcJp7K+hByWSfK+y7v5JS","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":385953},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","types":"types/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":"./plugins/expo-plugin.js","./plugins/xtremepush":{"types":"./plugins/xtremepush.d.ts","default":"./plugins/xtremepush.js"}},"gitHead":"ab38670baa36f68bd37177d72b59c7d2f3270c00","scripts":{"lint":"node scripts/lint-package.js","test":"node scripts/run-node-tests.js","test:api":"node scripts/run-node-tests.js tests/js-api","typecheck":"node scripts/run-typecheck.js","test:config":"node scripts/run-node-tests.js plugins/__tests__/unit plugins/__tests__/integration tests/config-plugin","test:package":"node scripts/check-package-integrity.js","test:regression":"node scripts/run-node-tests.js tests/regression","example:prebuild":"node scripts/run-example-prebuild.js example","validate:release":"node scripts/validate-release.js","validate:ios:local":"node scripts/local-ios-smoke.js example","example:assert-config":"node scripts/assert-example-config.js example","validate:android:local":"node scripts/local-android-smoke.js example","example:assert-prebuild":"node scripts/assert-example-prebuild.js example"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.12.1","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"26.0.0","dependencies":{"@expo/config-plugins":"^8.0.0"},"typesVersions":{"*":{"plugins/xtremepush":["plugins/xtremepush.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0","typescript":"^5.8.3"},"peerDependencies":{"expo":">=51.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.3.1_1780612335695_0.8945196663463653","host":"s3://npm-registry-packages-npm-production"}},"1.3.2":{"name":"xtremepush-expo-plugin","version":"1.3.2","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.3.2","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"bin":{"xtremepush-verify-build":"scripts/verify-build.js"},"dist":{"shasum":"71a41439f6bf2aad44651491fced8734b28a4f11","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.3.2.tgz","fileCount":28,"integrity":"sha512-LDtIUiJfitjy6rl5sQ4FjCGc7w8ndTJuUDH0UOWxBy8FY/xdTm1YDKFdnJKkc9VUXmUZ8V+YcfprD9jaCZ5wIQ==","signatures":[{"sig":"MEUCICrJIUkNy84cAJbVu07iO4/OirxmmQwQfI9PEqnFnMHTAiEAp0FEjlB+qo/NQreIkTrIOT4IJTphWklP+0genwPJqoM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":489524},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","types":"types/index.d.ts","engines":{"node":">=20.19.4"},"exports":{".":"./plugins/expo-plugin.js","./plugins/xtremepush":{"types":"./plugins/xtremepush.d.ts","default":"./plugins/xtremepush.js"}},"gitHead":"680d0a7a25deb1b10f04f9badda8f01dfa1b084c","scripts":{"lint":"node scripts/lint-package.js","test":"node scripts/run-node-tests.js","test:api":"node scripts/run-node-tests.js tests/js-api","typecheck":"node scripts/run-typecheck.js","test:config":"node scripts/run-node-tests.js tests/unit tests/integration tests/config-plugin","test:package":"node scripts/check-package-integrity.js","test:prebuild":"node scripts/prebuild-smoke.js","test:regression":"node scripts/run-node-tests.js tests/regression","example:prebuild":"node scripts/run-example-prebuild.js example","validate:release":"node scripts/validate-release.js","validate:ios:local":"node scripts/local-ios-smoke.js example","example:assert-config":"node scripts/assert-example-config.js example","validate:android:local":"node scripts/local-android-smoke.js example","example:assert-prebuild":"node scripts/assert-example-prebuild.js example"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.16.0","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"26.3.0","typesVersions":{"*":{"plugins/xtremepush":["plugins/xtremepush.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0","typescript":"^5.8.3","@expo/config-plugins":"^10.0.0"},"peerDependencies":{"expo":">=51.0.0","@expo/config-plugins":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.3.2_1782066536678_0.7043724582521433","host":"s3://npm-registry-packages-npm-production"}},"1.3.3":{"name":"xtremepush-expo-plugin","version":"1.3.3","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.3.3","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"bin":{"xtremepush-verify-build":"scripts/verify-build.js"},"dist":{"shasum":"969958a9c028d0bee64b10c8038c60cb9048e622","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.3.3.tgz","fileCount":28,"integrity":"sha512-gzpaS8JcBExH6eAAxyCP6i6yxctSIIxIPH/dMbGvB59GXm71J4gS0HD0h+iF0e26OZ+HAS9eGdHL58ESDknjUw==","signatures":[{"sig":"MEQCIGXZqwL1K2AHzt3yvVp5VnOQb/TNDxTc0EcbgMhlY652AiBAePjzo6jC1hC8M57rG3o/jYEOFttiEUeefT9QWZR5hQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":510469},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","types":"types/index.d.ts","engines":{"node":">=20.19.4"},"exports":{".":"./plugins/expo-plugin.js","./plugins/xtremepush":{"types":"./plugins/xtremepush.d.ts","default":"./plugins/xtremepush.js"}},"gitHead":"d327d509c5cc68f783678378e1b1cf30ec1aa3e4","scripts":{"lint":"node scripts/lint-package.js","test":"node scripts/run-node-tests.js","test:api":"node scripts/run-node-tests.js tests/js-api","typecheck":"node scripts/run-typecheck.js","test:config":"node scripts/run-node-tests.js tests/unit tests/integration tests/config-plugin","test:package":"node scripts/check-package-integrity.js","test:prebuild":"node scripts/prebuild-smoke.js","test:regression":"node scripts/run-node-tests.js tests/regression","example:prebuild":"node scripts/run-example-prebuild.js example","validate:release":"node scripts/validate-release.js","validate:ios:local":"node scripts/local-ios-smoke.js example","example:assert-config":"node scripts/assert-example-config.js example","validate:android:local":"node scripts/local-android-smoke.js example","example:assert-prebuild":"node scripts/assert-example-prebuild.js example"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.17.0","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"26.4.0","typesVersions":{"*":{"plugins/xtremepush":["plugins/xtremepush.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0","typescript":"^5.8.3","@expo/config-plugins":"^10.0.0"},"peerDependencies":{"expo":">=51.0.0","@expo/config-plugins":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.3.3_1783970339597_0.04771118843759847","host":"s3://npm-registry-packages-npm-production"}},"1.3.4":{"name":"xtremepush-expo-plugin","version":"1.3.4","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","_id":"xtremepush-expo-plugin@1.3.4","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"bin":{"xtremepush-verify-build":"scripts/verify-build.js"},"dist":{"shasum":"cbbab8a70ea7aec196094e06cc00e9dd383d75a8","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.3.4.tgz","fileCount":28,"integrity":"sha512-MhkJR6z6U7CNQdA1VP9TAbH/ZWKDz4j/NxOakh9DvZDyi0eSx4AaXTAPeFFJfCUEEjxlIJu2wQ73S3Xl2kbdfg==","signatures":[{"sig":"MEUCIGYnseUHiiCCVoq05CHgQB9wCaH9IOj2LighfxEPTZf6AiEAsc/usjnPgxaqusUQ0baPNMKtdErxhfme+tAkvR8d+VA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":527523},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"main":"plugins/expo-plugin.js","types":"types/index.d.ts","engines":{"node":">=20.19.4"},"exports":{".":"./plugins/expo-plugin.js","./plugins/xtremepush":{"types":"./plugins/xtremepush.d.ts","default":"./plugins/xtremepush.js"}},"gitHead":"5c0485507965d106e1e138350ba5dcbb3e29e1e2","scripts":{"lint":"node scripts/lint-package.js","test":"node scripts/run-node-tests.js","test:api":"node scripts/run-node-tests.js tests/js-api","typecheck":"node scripts/run-typecheck.js","test:config":"node scripts/run-node-tests.js tests/unit tests/integration tests/config-plugin","test:package":"node scripts/check-package-integrity.js","test:prebuild":"node scripts/prebuild-smoke.js","test:regression":"node scripts/run-node-tests.js tests/regression","example:prebuild":"node scripts/run-example-prebuild.js example","validate:release":"node scripts/validate-release.js","validate:ios:local":"node scripts/local-ios-smoke.js example","example:assert-config":"node scripts/assert-example-config.js example","validate:android:local":"node scripts/local-android-smoke.js example","example:assert-prebuild":"node scripts/assert-example-prebuild.js example"},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"repository":{"url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git","type":"git"},"_npmVersion":"11.17.0","description":"XtremePush Expo Config Plugin","directories":{},"_nodeVersion":"26.4.0","typesVersions":{"*":{"plugins/xtremepush":["plugins/xtremepush.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"expo":"^53.0.0","typescript":"^5.8.3","@expo/config-plugins":"^10.0.0"},"peerDependencies":{"expo":">=51.0.0","@expo/config-plugins":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/xtremepush-expo-plugin_1.3.4_1784673691072_0.7079903574278645","host":"s3://npm-registry-packages-npm-production"}},"1.3.5":{"name":"xtremepush-expo-plugin","version":"1.3.5","description":"XtremePush Expo Config Plugin","main":"plugins/expo-plugin.js","types":"types/index.d.ts","exports":{".":"./plugins/expo-plugin.js","./plugins/xtremepush":{"types":"./plugins/xtremepush.d.ts","default":"./plugins/xtremepush.js"}},"bin":{"xtremepush-verify-build":"scripts/verify-build.js"},"typesVersions":{"*":{"plugins/xtremepush":["plugins/xtremepush.d.ts"]}},"scripts":{"lint":"node scripts/lint-package.js","typecheck":"node scripts/run-typecheck.js","test":"node scripts/run-node-tests.js","test:api":"node scripts/run-node-tests.js tests/js-api","test:config":"node scripts/run-node-tests.js tests/unit tests/integration tests/config-plugin","test:package":"node scripts/check-package-integrity.js","test:regression":"node scripts/run-node-tests.js tests/regression","test:prebuild":"node scripts/prebuild-smoke.js","example:assert-config":"node scripts/assert-example-config.js example","example:assert-prebuild":"node scripts/assert-example-prebuild.js example","example:prebuild":"node scripts/run-example-prebuild.js example","validate:android:local":"node scripts/local-android-smoke.js example","validate:ios:local":"node scripts/local-ios-smoke.js example","validate:release":"node scripts/validate-release.js"},"keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"author":{"name":"Xtremepush"},"license":"MIT","devDependencies":{"@expo/config-plugins":"^10.0.0","expo":"^53.0.0","typescript":"^5.8.3"},"repository":{"type":"git","url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git"},"homepage":"https://docs.xtremepush.com","bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"engines":{"node":">=20.19.4"},"peerDependencies":{"@expo/config-plugins":">=8.0.0","expo":">=51.0.0"},"expo":{"name":"xtremepush-expo-plugin","slug":"xtremepush-expo-plugin"},"gitHead":"2c15c1ef57b732b5dcef58c80b0775872cce8f6b","_id":"xtremepush-expo-plugin@1.3.5","_nodeVersion":"26.8.1","_npmVersion":"11.19.0","dist":{"integrity":"sha512-4u2y1fD4w/6W4syErHUe4qZCZK4Br9eUQPMWzBQSbir0zfvFeCyqNJ+Gzi/xV7xB09x0I4VR4bi49pawZ5SOBg==","shasum":"d032564c4e3b95bf8653c0e5b96d8ac5e8ef5425","tarball":"https://registry.npmjs.org/xtremepush-expo-plugin/-/xtremepush-expo-plugin-1.3.5.tgz","fileCount":28,"unpackedSize":546103,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHRf5P32wf9AHZNiTWDa6AhDGBBfndsDJSjsSPaQWF5kAiEAgyRV8jBDuzpmQnusg7D+A/5AUvZZ3F7VK6KmR6h5BAc="}]},"_npmUser":{"name":"xpadmin","email":"admin+npm@xtremepush.com"},"directories":{},"maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/xtremepush-expo-plugin_1.3.5_1788182880132_0.5953375788044148"},"_hasShrinkwrap":false}},"time":{"created":"2025-08-07T22:33:47.461Z","modified":"2026-08-31T13:28:00.467Z","1.0.5":"2025-07-18T10:31:59.013Z","1.0.0-beta.1":"2025-07-21T20:58:01.800Z","1.0.0":"2025-08-07T22:33:47.630Z","1.0.1":"2025-08-07T22:34:45.678Z","1.0.2":"2025-08-07T23:19:00.482Z","1.0.3":"2025-08-20T05:29:37.348Z","1.0.4":"2025-08-20T05:38:25.141Z","1.1.0":"2025-09-12T01:20:25.078Z","1.1.1":"2025-12-03T23:15:55.296Z","1.1.2":"2026-02-05T20:57:10.070Z","1.1.3":"2026-03-04T23:54:48.373Z","1.2.0":"2026-03-16T23:18:29.611Z","1.2.1-canary.0":"2026-03-16T23:41:12.757Z","1.2.2":"2026-03-24T23:08:54.411Z","1.2.3-rc.1":"2026-04-02T10:59:56.254Z","1.2.3":"2026-04-02T20:23:04.737Z","1.2.4":"2026-04-21T00:14:56.645Z","1.2.5":"2026-04-22T22:34:04.290Z","1.2.6":"2026-04-30T20:28:44.486Z","1.2.7":"2026-05-10T11:51:36.913Z","1.2.8":"2026-05-14T01:35:17.466Z","1.2.9-rc":"2026-05-17T20:03:42.813Z","1.2.9":"2026-05-18T00:38:57.778Z","1.3.0":"2026-06-01T18:51:30.027Z","1.3.1":"2026-06-04T22:32:15.859Z","1.3.2":"2026-06-21T18:28:56.817Z","1.3.3":"2026-07-13T19:18:59.791Z","1.3.4":"2026-07-21T22:41:31.230Z","1.3.5":"2026-08-31T13:28:00.307Z"},"bugs":{"url":"https://github.com/xtremepush/xtremepush-expo-plugin/issues"},"author":{"name":"Xtremepush"},"license":"MIT","homepage":"https://docs.xtremepush.com","keywords":["expo","config-plugin","xtremepush","push-notifications","ios-rich-media","service-extension","app-groups","eas-build","notification-service"],"repository":{"type":"git","url":"git+https://github.com/xtremepush/xtremepush-expo-plugin.git"},"description":"XtremePush Expo Config Plugin","maintainers":[{"name":"xpadmin","email":"admin+npm@xtremepush.com"}],"readme":"# XtremePush Expo Plugin\n\nExpo config plugin that integrates the XtremePush SDK functionality with full React Native module support for both iOS and Android platforms.\n\n- **Latest version:** 1.3.5\n- **Supported platforms:** iOS 15.0+, Android 5.0+ (API 21)\n- **Supported Expo SDK:** 51 through 55 (53+ recommended)\n- **Distribution:** managed Expo projects via EAS, or local `expo run:ios` / `expo run:android` builds. Does not work in Expo Go.\n\n---\n\n## Table of contents\n\n- [What's new in 1.3.5](#whats-new-in-135)\n- [Requirements](#requirements)\n- [Installation](#installation)\n- [Quick start](#quick-start)\n- [Plugin configuration reference](#plugin-configuration-reference)\n- [iOS setup](#ios-setup)\n  - [Apple Developer Portal](#apple-developer-portal)\n  - [APNs credentials](#apns-credentials)\n  - [Building with EAS](#building-with-eas-ios)\n  - [Verifying the build with `xtremepush-verify-build`](#verifying-the-build-with-xtremepush-verify-build)\n  - [Building locally with Xcode](#building-locally-with-xcode)\n- [Android setup](#android-setup)\n  - [Firebase project](#firebase-project)\n  - [`google-services.json` placement](#google-servicesjson-placement)\n  - [XtremePush dashboard credentials](#xtremepush-dashboard-credentials-android)\n  - [Building with EAS](#building-with-eas-android)\n- [JavaScript API](#javascript-api)\n  - [Module availability](#module-availability)\n  - [User identity](#user-identity)\n  - [Importing a user profile](#importing-a-user-profile-130)\n  - [Updating a user](#updating-a-user-140)\n  - [Channel subscription preferences](#channel-subscription-preferences-140)\n  - [Events, impressions, and tags](#events-impressions-and-tags)\n  - [Push permissions and registration](#push-permissions-and-registration)\n  - [Initial notification handling](#initial-notification-handling)\n  - [Inbox — built-in UI](#inbox--built-in-ui)\n  - [Inbox — custom UI](#inbox--custom-ui)\n  - [Event subscriptions](#event-subscriptions)\n- [Loyalty Widget](#loyalty-widget)\n- [Advanced topics](#advanced-topics)\n  - [Server region and custom URLs](#server-region-and-custom-urls)\n  - [Delivery receipts](#delivery-receipts)\n  - [Encrypted push](#encrypted-push)\n  - [Receiving deeplinks with encrypted push (cold start)](#receiving-deeplinks-with-encrypted-push-cold-start)\n  - [SSL certificate pinning](#ssl-certificate-pinning)\n  - [Custom Notification Service Extension](#custom-notification-service-extension)\n  - [Custom delivery receipt endpoints](#custom-delivery-receipt-endpoints)\n- [Validation codes](#validation-codes)\n- [Troubleshooting](#troubleshooting)\n- [Migration guides](#migration-guides)\n- [Changelog](#changelog)\n- [License](#license)\n\n---\n\n## What's new in 1.3.5\n\nImproved `refreshInboxBadge()` method returns server-confirmed unread count on demand. If your app sometimes shows a stale badge number after calling `getInboxMessages()` then `getInboxBadge()`, this version resolves the issue — `await refreshInboxBadge()` and render the resolved value.\n\n| Change | Impact |\n|---|---|\n| **`refreshInboxBadge()`** | Awaitable server refresh that resolves with the fresh unread count. Use it wherever you render the indicator (e.g. on screen mount) instead of a bare `getInboxBadge()` read after an await. |\n| **Always resolves** | Falls back to the cached counter if the network is unavailable or the refresh times out — it never hangs and never rejects on a slow network. |\n| **iOS + Android parity** | iOS awaits the SDK's `loadBadgeWithCompletion:`; Android uses a per-request `retrieveInboxBadge(XPCallbackHandler)` whose callback fires whether or not the count changed. |\n\n**No breaking API changes.** `getInboxBadge()`, `onInboxBadgeUpdate`, and every\nother public method are unchanged — `refreshInboxBadge()` is purely additive.\nAdopting the fix **requires a client code change** (call the new method) plus a\nnative rebuild (`npx expo prebuild --clean`, then a dev/release client build).\n\nSee [Unread badge count — `refreshInboxBadge` vs `getInboxBadge`](#unread-badge-count--refreshinboxbadge-vs-getinboxbadge) for the recommended usage pattern.\n\n<details>\n<summary>What shipped in 1.3.4</summary>\n\n\n1.3.4 hardens cold-start deeplink delivery under encrypted push. After 1.3.3\nintroduced native buffer-and-replay, some apps still missed the decrypted\ndeeplink when the SDK fired in a narrow window (React up but no JS listener yet),\nwhen another XtremePush event was subscribed first, or when iOS cleared the\nbuffer on a brief unsubscribe. This release closes those gaps.\n\n| Change | Impact |\n|---|---|\n| **Android: emit only when a deeplink JS listener exists** | Previously the bridge could emit as soon as the React instance was active, even before `onDeeplinkReceived` subscribed — the event was lost. Emission now waits for a matching JS listener; otherwise the value is buffered and replayed on subscribe. |\n| **Event-specific replay (iOS + Android)** | Subscribing to inbox badge / message-response / loyalty no longer flushes a pending deeplink into the void. Each content event is replayed only when *that* event's listener attaches. |\n| **iOS: earlier SDK handler registration** | Deeplink / message-response handlers are registered before `applicationDidFinishLaunching` (and again safely from a C constructor / module init), so a cold-start decrypt can be captured even before the RN module exists. |\n| **iOS: `stopObserving` preserves the pending buffer** | Strict Mode remounts, Fast Refresh, or a short-lived splash subscription no longer wipe an unconsumed cold-start deeplink. Buffers clear only on true bridge teardown (`invalidate`). |\n\nSee [Receiving deeplinks with encrypted push (cold start)](#receiving-deeplinks-with-encrypted-push-cold-start) for the full client integration guide.\n\n</details>\n\n<details>\n<summary>What shipped in 1.3.3 </summary>\n\n| Change | Impact |\n|---|---|\n| **Cold-start buffer-and-replay** | First native buffer of decrypted deeplink / message-response for cold start. Opt-in via `deeplinkCallback` / `messageResponseCallback`. |\n| **`updateUser(payload)`** | JS API for the SDK `userUpdate` operation. See [Updating a user](#updating-a-user-133). |\n| **Channel subscription preferences** | Per-topic consent helpers. See [Channel subscription preferences](#channel-subscription-preferences-133). |\n| **Expo SDK 54 / 55 compatibility** | `@expo/config-plugins` as a peer dependency; Node `>=20.19.4`. |\n\n</details>\n\n---\n\n## Requirements\n\n### System\n- **Node.js** 20.19.4 or later (required by Expo SDK 54+; older SDKs work on Node 18, now end-of-life)\n- **Expo SDK** 51 or later (53+ recommended; SDK 54 and 55 supported)\n- **React Native** — whatever version your Expo SDK ships (SDK 51 → RN 0.74, SDK 55 → RN 0.79+). You don't pin this yourself; Expo does.\n- **EAS CLI** 18 or later (only if building with EAS)\n\n> The plugin uses `@expo/config-plugins` as a **peer dependency** — it resolves to the version your Expo SDK already provides (8.x on SDK 51 through 55.x on SDK 55). No action is required on your part.\n\n### iOS\n- **Deployment target** 15.0 or later (the plugin sets this automatically for the NSE)\n- **Xcode** — the version your Expo SDK requires (Xcode 15+ for SDK 51–53, Xcode 16+ for SDK 54–55)\n- **CocoaPods** latest\n- An **Apple Developer Program** membership (paid, individual or organisation)\n- For rich media or delivery receipts, the ability to register an App Group identifier in Apple Developer Portal\n\n### Android\n- **minSdkVersion** 21 (Android 5.0)\n- **targetSdkVersion** 34 (Android 14)\n- **Gradle** 8.0 or later\n- **Google Play Services** for FCM\n- A **Firebase project** with an Android app entry whose package name matches `android.package`\n\n---\n\n## Installation\n\n```bash\n# npm\nnpm install xtremepush-expo-plugin\n\n# yarn\nyarn add xtremepush-expo-plugin\n\n# pnpm\npnpm add xtremepush-expo-plugin\n```\n\nThe plugin pulls in the native iOS and Android XtremePush SDKs at build time via CocoaPods and Gradle respectively. There's no separate native install step.\n\n---\n\n## Quick start\n\nThis config enables basic push delivery:\n\n```js\n// app.config.js\nexport default {\n  expo: {\n    name: 'YourApp',\n    slug: 'your-app',\n    ios: {\n      bundleIdentifier: 'com.yourcompany.yourapp',\n    },\n    android: {\n      package: 'com.yourcompany.yourapp',\n      googleServicesFile: './google-services.json',\n    },\n    plugins: [\n      ['xtremepush-expo-plugin', {\n        applicationKey: 'YOUR_XTREMEPUSH_APP_KEY',\n        iosAppKey: 'YOUR_IOS_APP_KEY',\n        androidAppKey: 'YOUR_ANDROID_APP_KEY',\n        googleSenderId: 'YOUR_FCM_SENDER_ID',\n      }],\n    ],\n  },\n};\n```\n\nThen:\n\n```bash\nnpx expo prebuild --clean\n```\n\nThat gets you basic push delivery. To enable rich media and delivery receipts on iOS — recommended for production — see [Quick start with rich media + delivery receipts](#quick-start-with-rich-media--delivery-receipts) below.\n\n### Quick start with rich media + delivery receipts\n\n```js\n// app.config.js\nexport default {\n  expo: {\n    name: 'YourApp',\n    slug: 'your-app',\n    ios: {\n      bundleIdentifier: 'com.yourcompany.yourapp',\n    },\n    android: {\n      package: 'com.yourcompany.yourapp',\n      googleServicesFile: './google-services.json',\n    },\n    plugins: [\n      ['xtremepush-expo-plugin', {\n        applicationKey: 'YOUR_XTREMEPUSH_APP_KEY',\n        googleSenderId: 'YOUR_FCM_SENDER_ID',\n\n        // iOS rich media + delivery receipts\n        enableRichMedia: true,\n        enableDeliveryReceipts: true,\n        iosAppGroupIdentifier: 'group.com.yourcompany.yourapp.xtremepush.suit',\n        devTeam: 'ABCDE12345',                      // your Apple Team ID\n      }],\n    ],\n    extra: {\n      eas: {\n        projectId: 'your-eas-project-id',           // run `eas init` to populate\n      },\n    },\n  },\n};\n```\n\n> The plugin auto-injects the `extra.eas.build.experimental.ios.appExtensions` block at prebuild. **Do not write it by hand.** See [Apple Developer Portal](#apple-developer-portal) for the one-time Apple-side setup.\n\n---\n\n## Plugin configuration reference\n\nEvery option goes inside the plugin's options object in `app.config.js` / `app.json`:\n\n```js\nplugins: [\n  ['xtremepush-expo-plugin', { /* options here */ }],\n]\n```\n\n### Required\n\n| Option | Type | Description |\n|---|---|---|\n| `applicationKey` | `string` | Your XtremePush application key (from the dashboard). |\n| `googleSenderId` | `string` | Firebase numeric Sender ID. Required for Android push. |\n\n### Required when an NSE is created\n\n(i.e. when `enableRichMedia` or `enableDeliveryReceipts` is `true`.)\n\n| Option | Type | Description |\n|---|---|---|\n| `devTeam` | `string` | Apple Developer Team ID (e.g. `'ABCDE12345'`). The plugin throws [`XP_E003`](#xp_e003) at prebuild if missing. Find it at [developer.apple.com → Membership](https://developer.apple.com/account#MembershipDetailsCard) or in the output of `eas credentials -p ios`. |\n\n### Push permission control\n\n| Option | Type | Default | Description |\n|---|---|---|---|\n| `enablePushPermissions` | `boolean` | `true` | Auto-request the OS push prompt at launch. Set to `false` to defer until you call [`requestNotificationPermissions()`](#push-permissions-and-registration) from JS. Also controls whether `POST_NOTIFICATIONS` is added to the Android manifest. |\n\n### Feature flags\n\n| Option | Type | Default | Description |\n|---|---|---|---|\n| `enableRichMedia` | `boolean` | `false` | iOS rich media (image/video). Creates the Notification Service Extension. |\n| `enableDeliveryReceipts` | `boolean` | `false` | Push delivery receipts. iOS: also creates the NSE. Android: requires SDK ≥ 7.9.0. |\n| `enableEncryptedPush` | `boolean` | `false` | iOS encrypted push payloads. Requires uploading the public key in the dashboard. |\n| `enableEncryptedMessages` | `boolean` | `false` | Android encrypted messages. Requires Android SDK ≥ 8.1.0 plus a dashboard-side key. |\n| `enableInAppMessaging` | `boolean` | `true` | In-app message rendering. |\n| `enableLocationServices` | `boolean` | `true` | Adds location permissions on Android (`ACCESS_FINE_LOCATION`, `ACCESS_COARSE_LOCATION`, `ACCESS_BACKGROUND_LOCATION`) and the iOS usage descriptions. Set to `false` if you don't use location features — recommended to avoid Play / App Store review scrutiny. |\n| `enableStartSession` | `boolean` | `true` | Android `setEnableStartSession(true)` — app-launch session tracking. |\n| `enableInboxBadge` | `boolean` | `true` | Android `setInboxBadgeEnabled(true)` — inbox unread counter. |\n| `enableLoyalty` | `boolean` | `false` | Loyalty Widget integration. Requires `loyaltyEndpoint` and `loyaltyTokenRefreshCallback` ([`XP_E004`](#xp_e004) / [`XP_E005`](#xp_e005)). See [Loyalty Widget](#loyalty-widget). |\n| `enableDebugLogs` | `boolean` | `false` | Verbose SDK logging on both platforms. |\n\n### iOS\n\n| Option | Type | Default | Description |\n|---|---|---|---|\n| `iosAppKey` | `string` | `applicationKey` | iOS-specific application key override. |\n| `iosAppGroupIdentifier` | `string` | auto-derived | App Group shared between the main app and NSE. **Must end with `.xtremepush.suit`** when `enableDeliveryReceipts` is true ([`XP_E001`](#xp_e001) otherwise). Auto-derived as `group.<bundleId>.xtremepush.suit` for delivery receipts, or `group.<bundleId>.xtremepush` for rich-media-only. |\n| `iosAppGroup` | `string` | unset | Legacy alias for `iosAppGroupIdentifier`, used when only rich media is enabled. Prefer `iosAppGroupIdentifier`. |\n| `nseTargetName` | `string` | `'XtremePushNotificationServiceExtension'` | Override the NSE Xcode target name. Almost never needed. |\n| `iosSdkVersion` | `string` | `'6.1'` | Pin the `Xtremepush-iOS-SDK` CocoaPods version (e.g. `'6.1'` produces `pod 'Xtremepush-iOS-SDK', '~> 6.1'`). |\n| `apsEnvironment` | `'development'` \\| `'production'` | auto for EAS | (1.2.9+) Auto-derived to `'production'` when an NSE is created on an EAS project. Override only if you build with an EAS Development-type provisioning profile and need sandbox tokens. |\n\n### Android\n\n| Option | Type | Default | Description |\n|---|---|---|---|\n| `androidAppKey` | `string` | `applicationKey` | Android-specific application key override. |\n| `androidDependency` | `string` | `'ie.imobile.extremepush:XtremePush_lib:9.8.2'` | Full Gradle dependency string. Use this for Huawei HMS builds or custom artifacts. Builds against SDK >= 9.7.0 ([`XP_W008`](#xp_w008) below that); loyalty in-widget navigation needs >= 9.8.0 ([`XP_W009`](#xp_w009)). |\n| `androidDependencyVersion` | `string` | `'9.8.2'` | Override just the version of the default dependency. Builds against >= 9.7.0; loyalty path/params navigation needs >= 9.8.0 (gracefully ignored below that). Ignored if `androidDependency` is set. |\n\n### SSL certificate pinning\n\n| Option | Type | Default | Description |\n|---|---|---|---|\n| `enablePinning` | `boolean` | `false` | Enables iOS file-based pinning. Requires `certificatePath`. |\n| `certificatePath` | `string` | unset | Path (relative to project root) to your `.der` certificate. Used for both the main app and the NSE. |\n| `serverExpectedPublicKey` | `string` | unset | Android public-key pin. Hex-encoded SubjectPublicKeyInfo. Independent of the iOS file-based options. |\n\n### Server region\n\n| Option | Type | Default | Description |\n|---|---|---|---|\n| `useUsServer` | `boolean` | `false` | Use the US data centre (`https://sdk.us.xtremepush.com`). |\n| `serverUrl` | `string` | unset | Custom XtremePush server URL. Takes precedence over `useUsServer`. |\n| `usServerUrl` | `string` | `'https://sdk.us.xtremepush.com'` | Override the default US URL when `useUsServer` is `true`. |\n\n### Delivery receipts\n\n| Option | Type | Default | Description |\n|---|---|---|---|\n| `deliveryReceiptsEndpoint` | `string` | unset | If set, receipts POST to this URL instead of XtremePush. Both platforms. |\n\n### Loyalty Widget\n\nEnabled by `enableLoyalty: true`. Both options below are **required** when loyalty is enabled — prebuild fails with [`XP_E004`](#xp_e004) / [`XP_E005`](#xp_e005) otherwise. See [Loyalty Widget](#loyalty-widget) for the runtime API.\n\n| Option | Type | Default | Description |\n|---|---|---|---|\n| `loyaltyEndpoint` | `string` | unset | The project/environment-specific loyalty endpoint as a full `https://` URL — the host follows the format `p<projectId>.p.loyalty.<env>.xtremepush.com`, e.g. `https://p123.p.loyalty.eu.xtremepush.com`. The scheme is required (iOS rejects a scheme-less value, and a bare host triggers [`XP_W007`](#xp_w007)). Injected via `setLoyaltyEndpoint(...)` at launch. Confirm the value with your onboarding team. |\n| `loyaltyTokenRefreshCallback` | `string` (event name) | unset | Event name the SDK emits when it needs a fresh JWT (the expiry fallback). Must match the `eventName` passed to [`onLoyaltyTokenRefresh`](#loyalty-widget). |\n\n### Callbacks\n\nThese three pairs require **both** a plugin option (which tells the native SDK to register a listener) and a JS subscription with the same event name. Without the plugin option, the native SDK never registers and your JS handler never fires.\n\n| Option | Type | JS subscription helper |\n|---|---|---|\n| `messageResponseCallback` | `string` (event name) | [`onMessageResponse`](#message-response-callback) |\n| `inboxBadgeCallback` | `string` (event name) | [`onInboxBadgeUpdate`](#inbox-badge-callback) |\n| `deeplinkCallback` | `string` (event name) | [`onDeeplinkReceived`](#deeplink-callback) |\n| `inboxInvalidatedCallback` | `string` (event name) | [`onInboxInvalidated`](#inbox-invalidated-callback) |\n| `loyaltyTokenRefreshCallback` | `string` (event name) | [`onLoyaltyTokenRefresh`](#loyalty-widget) |\n\n### Full example\n\n```js\n// app.config.js — every option populated\nexport default {\n  expo: {\n    plugins: [\n      ['xtremepush-expo-plugin', {\n        // Required\n        applicationKey: 'YOUR_APP_KEY',\n        googleSenderId: 'YOUR_FCM_SENDER_ID',\n\n        // Platform-specific keys (optional)\n        iosAppKey: 'IOS_KEY',\n        androidAppKey: 'ANDROID_KEY',\n\n        // Push behaviour\n        enablePushPermissions: true,\n        enableInAppMessaging: true,\n        enableLocationServices: false,\n        enableStartSession: true,\n        enableInboxBadge: true,\n        enableDebugLogs: false,\n\n        // Rich media + delivery receipts (creates iOS NSE)\n        enableRichMedia: true,\n        enableDeliveryReceipts: true,\n        deliveryReceiptsEndpoint: 'https://your-server.com/receipts',\n        iosAppGroupIdentifier: 'group.com.yourcompany.yourapp.xtremepush.suit',\n        devTeam: 'ABCDE12345',\n        nseTargetName: 'XtremePushNotificationServiceExtension',\n        iosSdkVersion: '6.1',\n\n        // Encryption (require dashboard-side keys)\n        enableEncryptedPush: true,\n        enableEncryptedMessages: true,\n\n        // SSL pinning\n        enablePinning: true,\n        certificatePath: 'assets/cert.der',\n        serverExpectedPublicKey: '30820122...010001',\n\n        // Server region\n        useUsServer: true,\n\n        // Custom Android dependency (e.g. Huawei) — builds against SDK >= 9.7.0;\n        // use >= 9.8.0 for full loyalty in-widget navigation\n        androidDependency: 'com.huawei.hms:XtremePush_lib:9.8.2',\n\n        // Loyalty Widget\n        enableLoyalty: true,\n        loyaltyEndpoint: 'https://p123.p.loyalty.eu.xtremepush.com',\n        loyaltyTokenRefreshCallback: 'onLoyaltyTokenRefresh',\n\n        // Callbacks\n        messageResponseCallback: 'onMessageResponse',\n        inboxBadgeCallback: 'onInboxBadgeUpdate',\n        deeplinkCallback: 'onDeeplinkReceived',\n        inboxInvalidatedCallback: 'onInboxInvalidated',\n      }],\n    ],\n  },\n};\n```\n\n---\n\n## iOS setup\n\n### Apple Developer Portal\n\nFor the most common configuration (rich media + delivery receipts), you need an **App Group identifier** registered before building. Recent eas-cli versions can create it for you — the credentials wizard prints `Created: group.<…>` when it does. If you don't see that line, register it manually using the steps below.\n\n1. Sign in at [developer.apple.com](https://developer.apple.com/account/resources/identifiers/list).\n2. Identifiers → `+` → **App Groups** → Continue.\n3. Identifier: `group.<your.bundle.id>.xtremepush.suit` — must match `iosAppGroupIdentifier` in your plugin config exactly. The `.suit` suffix is **required** by the XtremePush iOS SDK.\n4. Save.\n\nEAS auto-creates the **App IDs** (main app + NSE) on the first build. If you need to do this manually:\n\n1. Identifiers → `+` → App IDs → App → Continue.\n2. Bundle ID (Explicit): your bundle identifier.\n3. Tick capabilities: **Push Notifications**, **App Groups**.\n4. Save.\n5. Repeat for the NSE bundle ID: `<your.bundle.id>.XtremePushNotificationServiceExtension`.\n\nAfter both App IDs exist, click each one and configure the App Groups capability to point at the App Group from step 3 above.\n\n### APNs credentials\n\n#### APNs Certificate (`.p12`)\n\nUse this only if your provider mandates certificate-based APNs.\n\n1. Apple Developer Portal → **Certificates** → `+`.\n2. Choose either **Apple Push Notification service SSL (Sandbox)** for development, or **Apple Push Notification service SSL (Sandbox & Production)** for App Store / TestFlight.\n3. Continue → select your App ID → continue.\n4. Upload a Certificate Signing Request — generate one in Keychain Access → menu → **Certificate Assistant** → **Request a Certificate from a Certificate Authority** → save to disk.\n5. Upload the CSR → download the `.cer` → double-click to install in Keychain.\n6. In Keychain Access → My Certificates → expand to expose the private key → right-click → **Export** as `.p12`. Set a password.\n7. Upload to XtremePush dashboard → **Settings → iOS** with the password.\n\n### Building with EAS (iOS)\n\nAdd a `preview` profile to `eas.json` for sideloadable Ad-Hoc builds (for production App Store submission, see [Production builds](#production-builds)):\n\n```json\n{\n  \"cli\": { \"version\": \">= 18.0.0\", \"appVersionSource\": \"remote\" },\n  \"build\": {\n    \"development\": {\n      \"developmentClient\": true,\n      \"distribution\": \"internal\",\n      \"ios\": { \"simulator\": false }\n    },\n    \"preview\": {\n      \"distribution\": \"internal\",\n      \"ios\": { \"simulator\": false, \"buildConfiguration\": \"Release\" }\n    },\n    \"production\": {\n      \"autoIncrement\": true,\n      \"ios\": { \"resourceClass\": \"m-medium\" }\n    }\n  }\n}\n```\n\nRegister your test device once:\n\n```bash\neas device:create\n# Choose \"Website\" → open the URL on the iPhone in Safari → install the profile\n```\n\nBuild:\n\n```bash\neas build --platform ios --profile preview --clear-cache\n```\n\nWhen the credentials wizard runs, answer:\n\n| Prompt | Answer |\n|---|---|\n| Log in to your Apple account? | **yes**, then your Apple ID + 2FA |\n| (After login, watch for) `Synced capabilities` | Should print `Enabled: Push Notifications` (or `App Groups, Push Notifications`), or `No updates`. **If it says `Disabled`**, Ctrl+C — see [Troubleshooting](#disabled-push-notifications-during-credentials-sync) |\n| Reuse this distribution certificate? | **Y** |\n| Generate a new Apple Provisioning Profile? | **Y** |\n| Select devices for the ad hoc build | Pick your test iPhone (Space to toggle) |\n\nThe wizard runs once for the main target and once for the NSE — answer the same way for both.\n\n### Verifying the build with `xtremepush-verify-build`\n\nOnce the build completes (5–15 min), download the `.ipa` and inspect it before installing:\n\n```bash\nnpx xtremepush-verify-build ~/Downloads/your-build.ipa\n```\n\nExpected output (production build):\n\n```\n── Main app (YourApp.app) ─────────────────\nℹ Bundle ID:        com.yourcompany.yourapp\n✓ aps-environment:  production\nℹ Apple Team ID:    ABCDE12345\n✓ App Groups:       group.com.yourcompany.yourapp.xtremepush.suit\n\n── Extension (XtremePushNotificationServiceExtension.appex) ──\nℹ Bundle ID:        com.yourcompany.yourapp.XtremePushNotificationServiceExtension\n✓ aps-environment:  production\nℹ Apple Team ID:    ABCDE12345\n✓ App Groups:       group.com.yourcompany.yourapp.xtremepush.suit\n```\n\nBoth rows must show ✓ for `aps-environment` and `App Groups`. Failure modes flagged by the tool:\n\n| Symptom | Meaning | Fix |\n|---|---|---|\n| Main app `aps-environment` missing | Push capability not enabled on the main App ID | Apple Developer Portal → tick Push Notifications → re-run `eas build --clear-cache` |\n| NSE `aps-environment` missing | Push capability not enabled on the NSE App ID | Same fix on the NSE App ID |\n| Main and NSE `aps-environment` differ | Profiles regenerated against different environments | Regenerate both profiles together; `eas build --clear-cache` |\n| App Groups don't overlap | App Group not enabled on both App IDs | Wire it on both; rebuild with `--clear-cache` |\n\n> macOS-only: the verifier shells out to `security cms -D` to decode embedded mobileprovision files. iOS `.ipa`s are inspected on macOS in practice, so this isn't a real restriction.\n\nThen install:\n\n```bash\neas build:run --platform ios --latest\n```\n\nConnect the iPhone via cable. EAS detects it and installs the `.ipa` directly. Open the app, accept the push prompt, background and foreground once, then check the XtremePush dashboard. Within ~1 minute the device should show `Addressable: Yes`.\n\n### Building locally with Xcode\n\nLocal builds work for testing without going through EAS:\n\n```bash\nnpx expo run:ios --device\n```\n\nPick your connected iPhone from the device list. Xcode handles signing automatically using a Personal Team — push will work end-to-end as long as the App Group, App IDs, and APNs credential are configured (see above).\n\n> Local builds use `personalTeam` profiles which are sandbox-only and limited to 7-day install duration. For longer-term testing on a real device, use the EAS `preview` profile.\n\n### Production builds\n\nFor App Store submission:\n\n```bash\neas build --platform ios --profile production\neas submit --platform ios --latest\n```\n\nEAS uses an App Store distribution certificate and an App Store provisioning profile. The verifier should still show `aps-environment: production` on both rows (production `.p8` or `.p12` covers Ad-Hoc, App Store, and internal-distribution).\n\n---\n\n## Android setup\n\n### Firebase project\n\n1. Sign in at [console.firebase.google.com](https://console.firebase.google.com) → create a project (or reuse one).\n2. Add an Android app:\n   - **Package name** must match `android.package` in `app.config.js` exactly.\n   - SHA-1 is optional for FCM; required only for additional Firebase services.\n3. Download `google-services.json` from the Android app's settings.\n4. Open Project Settings → Cloud Messaging → copy the numeric **Sender ID** (12 digits). This goes into `googleSenderId` in your plugin config.\n\n### `google-services.json` placement\n\nPlace the file at the **project root** (not `android/app/`) and reference it from `app.json`:\n\n```json\n\"android\": {\n  \"package\": \"com.yourcompany.yourapp\",\n  \"googleServicesFile\": \"./google-services.json\"\n}\n```\n\n`expo prebuild` copies it into `android/app/` on every prebuild. Putting it at the root keeps it portable across machines and visible to EAS uploads (the default `.gitignore` excludes `android/`, which would otherwise hide the file from the EAS build server).\n\n> **Do not commit secrets.** If your Firebase project is shared, treat `google-services.json` as sensitive; use [EAS file environment variables](https://docs.expo.dev/build-reference/variables/#using-secrets-in-environment-variables) to inject it at build time instead of committing it.\n\n### XtremePush dashboard credentials (Android)\n\nModern Firebase projects use the FCM HTTP v1 API, which requires a **Service Account JSON key**:\n\n1. Firebase Console → Project Settings → **Service Accounts** tab → **Generate new private key**.\n2. Save the JSON file.\n3. XtremePush dashboard → **Settings → Android** for your app → upload the Service Account JSON.\n\n(If you're on the legacy FCM Server Key flow, upload that instead — but Google has deprecated it.)\n\n### Building with EAS (Android)\n\n```bash\neas build --platform android --profile preview\n```\n\nThe credentials wizard for Android is much simpler than iOS — just one prompt:\n\n```\n✔ Generate a new Android Keystore? › (Y/n)\n```\n\nAnswer **Y**. EAS generates a keystore for internal-distribution builds. No Apple Developer-equivalent setup, no certificates to manage.\n\nWhen the build completes:\n\n```bash\neas build:run --platform android --latest\n```\n\nWith your phone connected via USB and **USB Debugging enabled** (Settings → System → Developer options). The `.apk` installs directly. Or scan the QR code from the EAS terminal output to install over Wi-Fi.\n\nAfter install: open the app, accept the notification permission prompt (Android 13+), confirm the device shows in the XtremePush dashboard, send a test campaign. Both Android push and rich-media images render through the FCM/XtremePush pipeline; the iOS NSE setup has no equivalent on Android.\n\n---\n\n## JavaScript API\n\nImport from `xtremepush-expo-plugin/plugins/xtremepush`. Every public function is listed below. TypeScript users can also import types from the package root.\n\n```ts\nimport {\n  // Identity\n  setUser, setExternalId, setLanguage, importUser, updateUser,\n  updatePushSubscriptionPreferences,\n  updateEmailSubscriptionPreferences,\n  updateSmsSubscriptionPreferences,\n\n  // Tracking\n  hitEvent, hitEventWithValue, hitEventWithValues, hitImpression,\n  hitTag, hitTagWithValue,\n\n  // Push\n  requestNotificationPermissions,\n  getInitialNotification,\n\n  // Inbox UI\n  openInbox,\n\n  // Inbox APIs\n  getInboxMessages, getInboxBadge, refreshInboxBadge, deleteInboxMessage,\n  reportMessageOpened, reportMessageClicked,\n\n  // Subscriptions\n  onMessageResponse, onInboxBadgeUpdate, onDeeplinkReceived,\n  onInboxInvalidated, onLoyaltyTokenRefresh,\n\n  // Loyalty Widget\n  setLoyaltyToken, openLoyalty, getLoyaltyUrl,\n  getLoyaltyInjectedJavaScript, handleLoyaltyWebViewMessage,\n\n  // Diagnostics\n  isAvailable, constants,\n\n  // Deprecated — not implemented in this version, will be removed in a future\n  // release. Both resolve to null; do not use in new code.\n  checkPushNotificationStatus, getCurrentDeviceToken,\n} from 'xtremepush-expo-plugin/plugins/xtremepush';\n\nimport type {\n  XtremePushPluginConfig,\n  XtremePushNotificationPayload,\n  XtremePushNativeModule,\n  XtremePushMessageResponseEvent,\n  XtremePushInboxBadgeEvent,\n  XtremePushDeeplinkEvent,\n  XtremePushInboxInvalidatedEvent,\n  XtremePushSubscription,\n  InboxMessage,\n} from 'xtremepush-expo-plugin';\n```\n\n### Module availability\n\n```ts\nimport { isAvailable } from 'xtremepush-expo-plugin/plugins/xtremepush';\n\nif (isAvailable()) {\n  // The native module is loaded.\n} else {\n  // Expo Go, web, or a build that hasn't run prebuild — fall back gracefully.\n}\n```\n\nThe plugin does not work in Expo Go. Use a development build (`npx expo run:ios` / `npx expo run:android`) or an EAS build.\n\n### User identity\n\n```ts\nimport { setUser, setExternalId } from 'xtremepush-expo-plugin/plugins/xtremepush';\n\nsetUser('user@example.com');           // your primary user ID\nsetExternalId('CRM-12345');            // legacy / external CRM ID\n\n// On logout — pass empty string, null, or undefined to reset.\n// (1.2.8+: iOS reached parity with Android on this; previous versions\n// silently ignored empty strings on iOS.)\nsetUser('');\nsetExternalId('');\n```\n\n#### Identity changes invalidate the inbox (1.3.0+)\n\nWhen `setUser` or `setExternalId` is called with a value that differs from the\npreviously set identity, the bridge does three things automatically:\n\n1. **Clears the native inbox-item cache.** Otherwise `reportMessageOpened`,\n   `reportMessageClicked`, and `deleteInboxMessage` could latch onto a message\n   that belonged to the previous user.\n2. **Triggers an SDK-authoritative badge refresh.** The new badge value lands\n   via the existing `InboxBadgeUpdateListener` (Android) or\n   `XPushInboxBadgeChangeNotification` (iOS) and is forwarded to JS through\n   `onInboxBadgeUpdate` if you subscribe to it.\n3. **Emits `onInboxInvalidated`** so your React tree can drop locally cached\n   inbox state immediately, before the SDK round-trip in step 2 completes.\n\nEmpty / `null` / `undefined` values are treated as a single \"logged out\"\nidentity, so repeat logout calls do not look like a transition. The very\nfirst call (identity establishment) doesn't fire invalidation either.\n\nTo receive the JS event, set `inboxInvalidatedCallback` in plugin config and\nsubscribe with [`onInboxInvalidated`](#inbox-invalidated-callback). The native\nside-effects (cache clear, badge refresh) run regardless.\n\n#### Preferred language\n\n```ts\nimport { setLanguage } from 'xtremepush-expo-plugin/plugins/xtremepush';\n\nsetLanguage('es-MX');   // IETF BCP 47 tag\n```\n\n`setLanguage(code)` records the contact's **preferred** language as profile data.\nThere is no device-level language setter in the native SDKs — the device locale\nis derived automatically — so this is a thin convenience wrapper that forwards\n`importUser({ language: code })`. A few implications follow from that:\n\n- **It is fire-and-forget** (`void`). The underlying `importUser` promise is\n  awaited internally and any rejection is caught and logged. Call `importUser`\n  directly if you need the resolved/rejected result.\n- **Pair it with an established identity** (`setUser` / `setExternalId`) so the\n  attribute lands on the right contact, exactly as with [`importUser`](#importing-a-user-profile-130).\n- **Invalid input is ignored silently.** Empty strings, whitespace-only strings,\n  and non-string values are dropped without a call, so you can pass\n  `navigator.language` or a device-locale value unguarded.\n\n### Importing a user profile (1.3.0+)\n\n`importUser(preferences)` sends a profile payload to the SDK's `profileImport`\nendpoint — `XPush.importUser` on iOS, `PushConnector.importUser` on Android — and\nresolves with the SDK's response (or `null` when the SDK returns no body). Use it\nto seed or update a contact's attributes, tags, and channel subscriptions.\n\n```ts\nimport { setUser, importUser } from 'xtremepush-expo-plugin/plugins/xtremepush';\n\n// Establish identity FIRST so the import is associated with the right contact.\n// (Since 1.3.2 the bridge also injects that identity into the payload for you —\n// see \"Automatic identifier injection\" below.)\nsetUser('user@example.com');\n\ntry {\n  const response = await importUser({\n    email: 'user@example.com',\n    firstName: 'Xtreme',\n    lastName: 'Push',\n    attributes: {\n      tier: 'gold',\n      tags: ['vip', 'newsletter'],\n    },\n    subscriptions: { sms: true, email: true, push: false },\n  });\n\n  console.log('importUser ok:', response);\n} catch (error) {\n  switch (error.code) {\n    case 'ERR_NO_IDENTIFIER':\n      // No identifier could be supplied or resolved (see below). Call setUser()\n      // first, or retry once the device has registered with XtremePush.\n      break;\n    case 'ERR_IMPORT_USER':\n      // The backend rejected the import. error.message carries the reason;\n      // the SDK's structured fields (code, message, and the raw native\n      // response) are attached to error.userInfo where the platform provides them.\n      break;\n    case 'ERR_IMPORT_USER_INVALID_PAYLOAD': // Android — JSON conversion failed\n    case 'ERR_NOT_INITIALIZED':             // Android — SDK not initialised\n    case 'ERR_XPUSH_UNAVAILABLE':           // iOS — native module missing\n    default:\n      // 'TypeError' (no error.code) — input was not a plain object\n      console.warn('importUser failed:', error.code ?? error.name, error.message);\n  }\n}\n```\n\n**Input contract.** `importUser` rejects synchronously with `TypeError` for\n`null`, `undefined`, no-args, arrays, strings, numbers, and booleans. Pass a\nplain object. Nested objects and arrays are supported on both platforms.\n\n#### Automatic identifier injection (1.3.2+)\n\nThe `profileImport` endpoint **requires a profile identifier** in the request\nbody, and rejects an identifier-less request with HTTP 400 /\n`\"At least one profile identifier is required\"`. The SDK does **not** copy the\n`setUser` / `setExternalId` identity into this body for you.\n\nTo remove this footgun, the native bridge injects an identifier automatically\n**only when your payload does not already contain one** (`user_id`,\n`external_id`, or `device_id`). Resolution order:\n\n| Priority | Injected key | Source |\n|---|---|---|\n| 1 | `user_id` | The last value passed to `setUser`, or — if none — `setExternalId`. |\n| 2 | `device_id` | The XtremePush server-assigned device id, read from the SDK's `getDeviceInfo()` (Android) / `deviceInfo` (iOS) under the `XPushDeviceID` key. The anonymous fallback used when no user identity has been set. |\n\nThis produces three behaviours, depending on what you pass and what identity is set:\n\n```ts\n// 1. AUTHENTICATED — identity is set, payload has no identifier.\n//    → bridge injects { user_id: 'user@example.com' }\nsetUser('user@example.com');\nawait importUser({ firstName: 'Xtreme', attributes: { tier: 'gold' } });\n\n// 2. ANONYMOUS — no identity set, payload has no identifier.\n//    → bridge injects { device_id: '<XPushDeviceID>' } once the device has\n//      registered. If the device id is not yet available, rejects ERR_NO_IDENTIFIER.\nawait importUser({ attributes: { onboardingStep: 2 } });\n\n// 3. CLIENT-SUPPLIED — you provide the identifier yourself.\n//    → bridge leaves the payload UNTOUCHED (never overrides your value).\nawait importUser({ user_id: 'crm-42', email: 'user@example.com' });\n```\n\n**`ERR_NO_IDENTIFIER`.** When no identifier is in the payload, no\n`setUser` / `setExternalId` identity is set, *and* the device id is not yet\navailable (the device has not finished registering with XtremePush), the call\nrejects with `ERR_NO_IDENTIFIER` rather than letting the backend return a raw\nHTTP 400. Recover by calling `setUser(...)` first, or by retrying once\nregistration has completed (e.g. after the first successful push registration).\n\n> The device id only exists **after** the device successfully registers with\n> XtremePush. A fully-anonymous `importUser` fired at cold start may therefore\n> reject with `ERR_NO_IDENTIFIER` until registration completes — this is the\n> expected, catchable signal, not an error in your integration.\n\n\n### Updating a user (1.3.3+)\n\nUse `updateUser` to update channel subscriptions, preferences, and attributes\non an existing contact. It maps to `XPush.updateUserWith` (iOS) /\n`PushConnector.updateUser` (Android), which POST to the SDK's `userUpdate`\nendpoint (`/push/api/userUpdate`) — distinct from `importUser`'s `profileImport`.\n\n```ts\nimport { setUser, updateUser } from 'xtremepush-expo-plugin/plugins/xtremepush';\n\nsetUser('user@example.com');\n\ntry {\n  const response = await updateUser({\n    user_id: 'user@example.com',\n    push_subscription: 1,                   // integer 1/0, NOT true/false\n    push_subscription_preferences: {        // dynamic passthrough — any keys\n      marketing: 1,\n      transactional: 0,\n    },\n    email_subscription: 1,\n    my_attribute: { tier: 'gold' },\n  });\n\n  console.log('updateUser ok:', response);\n} catch (error) {\n  // error.code is one of:\n  //   ERR_UPDATE_USER                — backend rejected the update\n  //   ERR_UPDATE_USER_INVALID_PAYLOAD — payload was not valid JSON\n  //   ERR_NOT_INITIALIZED            — SDK not initialised (Android)\n  //   ERR_XPUSH_UNAVAILABLE          — native module missing (iOS)\n  //   TypeError                      — bad input shape (didn't reach native)\n}\n```\n\n**Host routing.** The request hits whatever host the SDK was initialised with —\nthe default (`api.xtremepush.com`), the US region (`useUsServer` /\n`usServerUrl`), or any custom `serverUrl` (e.g. a custom host). The native SDK\nbuilds the URL from its init config, so the configured host is inherited\nautomatically; nothing is hardcoded in the bridge.\n\n**Type fidelity (integers).** The `userUpdate` contract expects integer `1`/`0`\nfor flag fields like `push_subscription` — not booleans, and not `1.0`. The\npayload crosses the bridge as a JSON string and is parsed natively (`org.json`\non Android, `NSJSONSerialization` on iOS), which bypasses the `ReadableMap`\nnumber coercion that would otherwise turn `1` into `1.0`. Pass `1`/`0`\nexplicitly, and pass large 64-bit identifiers as strings (a JS `number` is a\ndouble).\n\n**Input contract.** Like `importUser`, `updateUser` rejects synchronously with\n`TypeError` for `null`, `undefined`, no-args, arrays, and primitives. Preference\nkeys are passed through dynamically — nothing is whitelisted.\n\n\n### Channel subscription preferences (1.3.3+)\n\nUse these methods to manage a contact's **per-category subscription preferences**\non a base channel — the dedicated SDK operation behind a self-built preference\nscreen (e.g. a list of toggles for `news`, `marketing`, `transactional`):\n\n- `updatePushSubscriptionPreferences(preferences)`\n- `updateEmailSubscriptionPreferences(preferences)`\n- `updateSmsSubscriptionPreferences(preferences)`\n\nEach takes a **flat `{ topic: boolean }` map** and resolves with the SDK's\nresponse (or `null`). Pass plain booleans — the bridge normalises each value to\nthe wire type the SDK expects per platform (**integer `1`/`0` on Android**,\n**boolean on iOS**), so you write the same JavaScript for both.\n\n```ts\nimport {\n  updatePushSubscriptionPreferences,\n} from 'xtremepush-expo-plugin/plugins/xtremepush';\n\n// A preference screen with three category toggles → one call:\ntry {\n  const response = await updatePushSubscriptionPreferences({\n    news: true,          // opted in\n    marketing: false,    // opted out\n    transactional: true,\n  });\n  console.log('push preferences updated:', response);\n} catch (error) {\n  // error.code:\n  //   ERR_UPDATE_SUBSCRIPTION_PREFERENCES               — backend rejected (e.g. a\n  //                                                        topic not defined under the channel)\n  //   ERR_UPDATE_SUBSCRIPTION_PREFERENCES_INVALID_PAYLOAD — payload was not valid JSON\n  //   ERR_NOT_INITIALIZED  — SDK not initialised (Android)\n  //   ERR_XPUSH_UNAVAILABLE — native module missing (iOS)\n  //   TypeError            — bad input shape (didn't reach native)\n  console.warn('preference update failed:', error.code, error.message);\n}\n```\n\nThe `email` and `sms` variants are identical in shape:\n\n```ts\nawait updateEmailSubscriptionPreferences({ newsletter: true, offers: false });\nawait updateSmsSubscriptionPreferences({ alerts: true });\n```\n\nA complete React preference screen wiring booleans straight into the call:\n\n```tsx\nimport { useState } from 'react';\nimport { View, Text, Switch, Button } from 'react-native';\nimport { updatePushSubscriptionPreferences } from 'xtremepush-expo-plugin/plugins/xtremepush';\n\nconst CATEGORIES = ['news', 'marketing', 'transactional'] as const;\n\nfunction PushPreferences() {\n  const [prefs, setPrefs] = useState({ news: true, marketing: false, transactional: true });\n\n  const toggle = (key: string) => setPrefs((p) => ({ ...p, [key]: !p[key] }));\n\n  return (\n    <View>\n      {CATEGORIES.map((key) => (\n        <View key={key} style={{ flexDirection: 'row', justifyContent: 'space-between' }}>\n          <Text>{key}</Text>\n          <Switch value={prefs[key]} onValueChange={() => toggle(key)} />\n        </View>\n      ))}\n      <Button\n        title=\"Save push preferences\"\n        onPress={() => updatePushSubscriptionPreferences(prefs).catch(console.warn)}\n      />\n    </View>\n  );\n}\n```\n\n**Two prerequisites for the topics to take effect:**\n\n1. **Define the categories first.** The topic keys (`news`, `marketing`, …) must\n   already exist as push-channel subscription preferences in your XtremePush\n   Consent Manager. If a key isn't defined under the channel, the SDK returns a\n   per-field error and the call rejects with\n   `ERR_UPDATE_SUBSCRIPTION_PREFERENCES`. The plugin cannot create categories —\n   that is dashboard configuration.\n2. **The master switch still gates delivery.** A device only receives push at\n   all if the overall `push_subscription` is enabled (it is by default). These\n   methods layer **category-level** control on top of that master switch. To\n   change the master switch itself, use `updateUser({ push_subscription: 1 })`\n   (integer `1`/`0`) — see [Updating a user](#updating-a-user-140).\n\n\n### Events, impressions, and tags\n\n```ts\nimport {\n  hitEvent, hitEventWithValue, hitEventWithValues,\n  hitImpression, hitTag, hitTagWithValue,\n} from 'xtremepush-expo-plugin/plugins/xtremepush';\n\n// Bare event\nhitEvent('app_opened');\n\n// Event with a single string value\nhitEventWithValue('purchase_completed', '49.99');\n\n// Event with key-value pairs (cross-platform)\nhitEventWithValues('product_added_to_basket', {\n  product_category: 'Sports',\n  product_name: 'Home Jersey',\n});\n\n// Page / screen impression\nhitImpression('home_page');\nhitImpression(`article_${articleId}`);\n\n// User-segmentation tag\nhitTag('vip');\nhitTagWithValue('user_level', 'gold');\n```\n\n> All values are forwarded as strings on Android (the SDK signature is `HashMap<String, String>`). Pass strings explicitly to keep cross-platform parity. Numbers and booleans are coerced; nested objects/arrays are dropped.\n\n> The native SDK silently ignores calls with an empty event name on iOS. Always pass non-empty strings.\n\n### Push permissions and registration\n\n```ts\nimport { requestNotificationPermissions } from 'xtremepush-expo-plugin/plugins/xtremepush';\n\nrequestNotificationPermissions();\n```\n\n#### Deferred prompt (recommended UX pattern)\n\nSet `enablePushPermissions: false` in plugin config to suppress the launch-time prompt, then call `requestNotificationPermissions()` from JS at a moment that makes sense for the user (e.g. after onboarding):\n\n```js\n// app.config.js\nenablePushPermissions: false,\n```\n\n```ts\n// after onboarding\nrequestNotificationPermissions();\n```\n\n> **Android note:** if you set `enablePushPermissions: false`, the plugin omits `POST_NOTIFICATIONS` from the manifest. To prompt later on Android 13+, add it manually:\n> ```xml\n> <uses-permission android:name=\"android.permission.POST_NOTIFICATIONS\" />\n> ```\n\n### Initial notification handling\n\nWhen a user taps a push to launch the app from a terminated state, you can retrieve the **raw OS transport** payload once on launch. Prefer this only for non-content metadata (ids) or when encrypted push is **off**.\n\n> Under **encrypted push**, do **not** use this API for `deeplink` / `title` / `text` / `data` — use [`onDeeplinkReceived`](#receiving-deeplinks-with-encrypted-push-cold-start) instead.\n\n```ts\nimport { useEffect } from 'react';\nimport { getInitialNotification } from 'xtremepush-expo-plugin/plugins/xtremepush';\n\nexport default function App() {\n  useEffect(() => {\n    getInitialNotification().then((payload) => {\n      if (payload?.id) {\n        // e.g. analytics — avoid navigating with payload.deeplink when encrypted\n      }\n    });\n  }, []);\n  return /* … */;\n}\n```\n\nThe payload is cleared after the first read — call it once on app start. Shape:\n\n```ts\n{\n  id?: string;                    // notification id\n  campaignId?: string;\n  title?: string;\n  text?: string;\n  deeplink?: string;\n  platform?: 'ios' | 'android';\n  receivedAt?: number;            // ms since epoch\n  badge?: number;                 // iOS only\n  data?: Record<string, any>;     // custom payload\n}\n```\n\n> **Encrypted push:** `getInitialNotification()` reads the raw OS transport payload, which is the pre-decryption copy — so with encrypted push enabled its content fields (`title`, `text`, `deeplink`, `data`) may come back as ciphertext. Do **not** use it to read a deeplink under encryption; subscribe to the `onDeeplinkReceived` callback instead, which delivers the SDK's decrypted output and is cold-start-safe (1.3.4+). See [Receiving deeplinks with encrypted push (cold start)](#receiving-deeplinks-with-encrypted-push-cold-start).\n\n### Inbox — built-in UI\n\n```ts\nimport { openInbox } from 'xtremepush-expo-plugin/plugins/xtremepush';\n\nopenInbox();   // opens the SDK's full-screen inbox UI\n```\n\n### Inbox — custom UI\n\n```ts\nimport {\n  getInboxMessages, getInboxBadge, refreshInboxBadge, deleteInboxMessage,\n  reportMessageOpened, reportMessageClicked,\n  onInboxBadgeUpdate,\n} from 'xtremepush-expo-plugin/plugins/xtremepush';\nimport type { InboxMessage } from 'xtremepush-expo-plugin';\n\n// Fetch a page (limit ≥ 1, offset ≥ 0; values are clamped by the JS wrapper).\nconst messages: InboxMessage[] = await getInboxMessages(20, 0);\n\n// Get an accurate, server-confirmed unread total on demand (1.3.5+).\n// Prefer this over getInboxBadge() when you need a correct value right now —\n// e.g. rendering an unread indicator on screen mount. See \"Unread badge count\"\n// below for why.\nconst unread = await refreshInboxBadge();\n\n// Report opens / clicks. reportMessageClicked also marks the message as\n// opened — don't call both for the same interaction.\nawait reportMessageOpened(message.identifier);\nawait reportMessageClicked(message.identifier, message.response.action.identifier);\n\n// Delete\nawait deleteInboxMessage(message.identifier);\n```\n\n#### Unread badge count — `refreshInboxBadge` vs `getInboxBadge`\n\nFor an unread indicator, use **`refreshInboxBadge()`**.\n\n```ts\nimport { refreshInboxBadge } from 'xtremepush-expo-plugin/plugins/xtremepush';\n\nconst unread = await refreshInboxBadge(); // accurate, server-confirmed\nsetUnreadCount(unread);\n```\n\nThere are two ways to read the count, and they are not interchangeable:\n\n| API | What it returns | Use it when |\n|---|---|---|\n| `getInboxBadge()` | The SDK's **cached** counter, as it is *right now*. Cheap, but only as fresh as the last refresh the SDK happened to perform. | You want a quick read and don't need it to reflect the very latest server state. |\n| `refreshInboxBadge()` (1.3.5+) | Performs an **on-demand server refresh and awaits it**, resolving with the fresh count. Always resolves (falls back to the cached counter if the network is unavailable or the refresh times out). | You need a correct value on demand — e.g. rendering the indicator on screen mount. |\n\n**Why `refreshInboxBadge` exists — a common pitfall.** A natural-looking pattern is to\ncall `getInboxMessages()` first \"to prime the cache\", then read `getInboxBadge()`:\n\n```ts\n// ❌ Racy — can return the PREVIOUS count\nawait getInboxMessages(20, 0);\nconst unread = await getInboxBadge();\n```\n\nThis is unreliable. `getInboxMessages()` and the badge refresh it triggers are **two\nindependent server round-trips**. `getInboxMessages()` resolves as soon as the *message\nlist* returns — but the refreshed *badge* lands on a separate, later path. So the\n`getInboxBadge()` read immediately after can execute before the new badge has landed and\nreturn the stale, previous count. It's timing-dependent, which is why it \"usually works\nbut sometimes shows the wrong number\".\n\n`refreshInboxBadge()` removes the race — it awaits the badge refresh itself, so a single\n`await` returns the correct value with no ordering dependency:\n\n```ts\n// ✅ Correct — one call, no ordering dependency\nconst unread = await refreshInboxBadge();\n```\n\n**Recommended pattern for an always-correct indicator.** Read on mount with\n`refreshInboxBadge()`, and — if you also want the indicator to update live while the\nscreen stays mounted (a push arrives, or a message is read elsewhere) — additionally\nsubscribe to [`onInboxBadgeUpdate`](#inbox-badge-callback):\n\n```ts\nuseEffect(() => {\n  let mounted = true;\n\n  // 1) Accurate value on mount (pull)\n  refreshInboxBadge()\n    .then((badge) => { if (mounted) setUnreadCount(badge); })\n    .catch(() => {});\n\n  // 2) Live updates while mounted (push) — optional; requires inboxBadgeCallback\n  const sub = onInboxBadgeUpdate('onInboxBadgeUpdate', ({ badge }) => {\n    if (mounted) setUnreadCount(badge);\n  });\n\n  return () => { mounted = false; sub.remove(); };\n}, []);\n```\n\n> **Note (Android):** `refreshInboxBadge()` issues its server refresh while the app is\n> foregrounded (a mounted screen is). If called with no foreground activity it resolves\n> promptly with the cached counter rather than blocking. Requires `enableInboxBadge`\n> (default `true`).\n\n`InboxMessage` shape (1.2.7+):\n\n```ts\ninterface InboxMessage {\n  identifier: string;\n  isOpened: boolean;\n  isClicked: boolean;\n  isDelivered: boolean;\n  createTimestamp: number;        // Unix milliseconds — pass directly to new Date()\n  expirationTimestamp: number | null;\n  style: Record<string, any>;\n  isCard: boolean;\n\n  response: {\n    message: {\n      identifier?: string;\n      campaignIdentifier?: string;\n      title?: string;\n      text?: string;\n      icon?: string;\n      data?: Record<string, any>;\n      payload?: Record<string, any>;\n    };\n    action: {\n      deeplink?: string;\n      url?: string;\n      identifier?: string;\n    };\n  };\n}\n```\n\n#### Error handling\n\n`getInboxMessages` rejects with one of two specific codes:\n\n| Code | Meaning | Recommended response |\n|---|---|---|\n| `ERR_INBOX_FETCH` | The SDK surfaced an error (network, auth, etc.) | Retry with backoff |\n| `ERR_SDK_NOT_READY` | Device not registered yet (distinct from \"inbox is empty\", which resolves with `[]`) | Retry after a short delay or after `onMessageResponse` fires |\n\n```ts\ntry {\n  const messages = await getInboxMessages(20, 0);\n  setMessages(messages);\n} catch (e: any) {\n  if (e.code === 'ERR_SDK_NOT_READY') {\n    setTimeout(loadInbox, 2000);\n  } else {\n    console.error('Inbox fetch failed:', e);\n  }\n}\n```\n\n### Event subscriptions\n\nAll event subscriptions take an event name (matching your plugin config) and a handler. They return `{ remove(): void }` — call `.remove()` from the cleanup function of your effect. The four inbox/push/deeplink subscriptions are below; the loyalty token-refresh subscription is covered in [Loyalty Widget](#loyalty-widget).\n\n#### Message response callback\n\nFires when the user taps a push notification.\n\n```ts\n// In plugin config:\n//   \"messageResponseCallback\": \"onMessageResponse\"\n\nimport { onMessageResponse } from 'xtremepush-expo-plugin/plugins/xtremepush';\n\nuseEffect(() => {\n  const sub = onMessageResponse('onMessageResponse', (event) => {\n    if (event.message?.deeplink) {\n      navigation.navigate(event.message.deeplink);\n    }\n  });\n  return () => sub.remove();\n}, [navigation]);\n```\n\nEvent shape:\n- `message`: `{ id, title, text, deeplink, campaignId, ...customFields }`\n- `response`: `Record<string, string>` — additional metadata\n\n#### Inbox badge callback\n\nFires when the inbox-wide unread count changes. This is a **push** model — good for\nupdating the indicator live while a screen is mounted. For an accurate value **on demand**\n(e.g. right when a screen mounts), pull it with\n[`refreshInboxBadge()`](#unread-badge-count--refreshinboxbadge-vs-getinboxbadge); the two\ncompose well.\n\n```ts\n// In plugin config:\n//   \"inboxBadgeCallback\": \"onInboxBadgeUpdate\"\n\nimport { onInboxBadgeUpdate } from 'xtremepush-expo-plugin/plugins/xtremepush';\n\nuseEffect(() => {\n  const sub = onInboxBadgeUpdate('onInboxBadgeUpdate', ({ badge }) => {\n    setUnreadCount(badge);\n  });\n  return () => sub.remove();\n}, []);\n```\n\n#### Deeplink callback\n\nFires when a deeplink is received — with the app in the foreground, and on a cold-start notification tap (the value is buffered natively and replayed once you subscribe, 1.3.4+). This is the recommended way to read a deeplink, and the **required** one under encrypted push — see [Receiving deeplinks with encrypted push (cold start)](#receiving-deeplinks-with-encrypted-push-cold-start).\n\n```ts\n// In plugin config:\n//   \"deeplinkCallback\": \"onDeeplinkReceived\"\n\nimport { onDeeplinkReceived } from 'xtremepush-expo-plugin/plugins/xtremepush';\n\nuseEffect(() => {\n  const sub = onDeeplinkReceived('onDeeplinkReceived', ({ deeplink }) => {\n    navigation.navigate(deeplink);\n  });\n  return () => sub.remove();\n}, [navigation]);\n```\n\n#### Inbox invalidated callback\n\nFires when `setUser` / `setExternalId` is called with a value that differs\nfrom the previously set identity. By the time the handler runs, the native\ninbox-item cache has been cleared and an SDK badge refresh is in flight; use\nthis as the signal to drop your JS-side inbox state and refetch.\n\n```ts\n// In plugin config:\n//   \"inboxInvalidatedCallback\": \"onInboxInvalidated\"\n\nimport { onInboxInvalidated } from 'xtremepush-expo-plugin/plugins/xtremepush';\n\nuseEffect(() => {\n  const sub = onInboxInvalidated('onInboxInvalidated', ({ reason }) => {\n    // reason: 'userChanged' | 'externalIdChanged'\n    setInboxMessages([]);\n    setUnreadCount(0);\n    // refetch under the new identity:\n    refreshInbox();\n  });\n  return () => sub.remove();\n}, []);\n```\n\nThe native cache clear and SDK badge refresh run unconditionally on identity\nchange. The JS event is opt-in: it only fires if `inboxInvalidatedCallback`\nis set in plugin config.\n\n---\n\n## Loyalty Widget\n\nThe Loyalty Widget shows a user's loyalty content (points, rewards, offers) in a\nweb view. Enable it with `enableLoyalty: true` plus [`loyaltyEndpoint`](#loyalty-widget)\nand [`loyaltyTokenRefreshCallback`](#loyalty-widget) in plugin config, then drive it\nfrom JavaScript.\n\n```js\nimport {\n  setLoyaltyToken,\n  openLoyalty,\n  getLoyaltyUrl,\n  onLoyaltyTokenRefresh,\n  getLoyaltyInjectedJavaScript,\n  handleLoyaltyWebViewMessage,\n} from 'xtremepush-expo-plugin/plugins/xtremepush';\n```\n\n### Authentication: set the token\n\nThe widget authenticates with a JWT minted by **your** backend (see the\nXtremePush \"Manage User Authentication\" guide). Set it **proactively** — typically\nright after login — and the SDK reuses it for every widget open:\n\n```js\n// After your user logs in and you've fetched their loyalty JWT:\nsetLoyaltyToken(jwt);\n```\n\n`onLoyaltyTokenRefresh` is the **expiry fallback**, not the primary path. The SDK\nemits it only when the loaded widget reports its token has expired. Fetch a fresh\nJWT and either return it (the wrapper forwards it to `setLoyaltyToken` for you) or\ncall `setLoyaltyToken` yourself:\n\n```js\nuseEffect(() => {\n  // eventName must match loyaltyTokenRefreshCallback in plugin config.\n  const sub = onLoyaltyTokenRefresh('onLoyaltyTokenRefresh', async () => {\n    const fresh = await fetchLoyaltyJwtFromYourBackend();\n    return fresh; // forwarded to setLoyaltyToken automatically\n  });\n  return () => sub.remove();\n}, []);\n```\n\n> The plugin requires `loyaltyTokenRefreshCallback` whenever `enableLoyalty` is\n> true, so always register this handler — even if you also set tokens proactively.\n> When the active user changes via `setUser` / `setExternalId`, the stored token is\n> cleared on both platforms so a new user never inherits the previous user's JWT.\n\n### Full-screen mode\n\n`openLoyalty` presents the widget natively as a full-screen view. Optionally pass a\npath and custom parameters:\n\n```js\nopenLoyalty();                                              // default view\nopenLoyalty('rewards');                                     // a specific section\nopenLoyalty('rewards', { 'color-mode': 'dark', lang: 'es' }); // with params\n```\n\n> **Android SDK < 9.8.0:** the `path` and `params` arguments to `openLoyalty` /\n> `getLoyaltyUrl` deep-link into a specific widget screen and require Android SDK\n> `9.8.0+`. On `9.7.x` the widget still opens (and `getLoyaltyUrl` still returns a\n> URL), but those arguments are ignored — you get the default screen, with a\n> one-time log line. See [`XP_W009`](#xp_w009). iOS is unaffected.\n\n**Deeplinks from full-screen mode** are routed through your normal deeplink\ncallback. Set `deeplinkCallback` in plugin config and subscribe with\n[`onDeeplinkReceived`](#deeplink-callback) — when the widget asks the app to open a\nURL, it arrives there. Without `deeplinkCallback` configured, loyalty redirects are\nsilently dropped.\n\n### Embedded WebView mode\n\nTo render the widget inside your own [`react-native-webview`](https://github.com/react-native-webview/react-native-webview),\nfetch the URL with `getLoyaltyUrl` and wire up the two bridge helpers. In this mode\nthe native SDK is not in the loop, so redirects and token-expiry signals reach you\nthrough the WebView's `onMessage` instead of the native deeplink callback:\n\n```jsx\nimport { WebView } from 'react-native-webview';\nimport {\n  getLoyaltyUrl,\n  setLoyaltyToken,\n  getLoyaltyInjectedJavaScript,\n  handleLoyaltyWebViewMessage,\n} from 'xtremepush-expo-plugin/plugins/xtremepush';\n\nfunction LoyaltyScreen({ navigation }) {\n  const [url, setUrl] = useState(null);\n\n  useEffect(() => {\n    // getLoyaltyUrl requires a token to have been set first (see above).\n    getLoyaltyUrl('rewards', { 'color-mode': 'light' }).then(setUrl);\n  }, []);\n\n  if (!url) return null;\n\n  return (\n    <WebView\n      source={{ uri: url }}\n      injectedJavaScriptBeforeContentLoaded={getLoyaltyInjectedJavaScript()}\n      onMessage={(event) =>\n        handleLoyaltyWebViewMessage(event, {\n          onTokenExpired: async () => {\n            const fresh = await fetchLoyaltyJwtFromYourBackend();\n            setLoyaltyToken(fresh); // also re-load the URL to apply it\n          },\n          onRedirect: (deeplink) => {\n            navigation.navigate(deeplink); // route however your app handles deeplinks\n          },\n        })\n      }\n    />\n  );\n}\n```\n\nBoth callbacks are optional — an absent `onTokenExpired` / `onRedirect` simply\nignores that signal. The injected bridge handles the platform differences for you\n(Android exposes a `window.Android` interface; iOS hooks `window.postMessage`), so\nthe same code works on both.\n\n---\n\n## Advanced topics\n\n### Server region and custom URLs\n\nBy default the SDK connects to the EU data centre. To use the US data centre:\n\n```js\n// app.config.js\n['xtremepush-expo-plugin', {\n  applicationKey: 'YOUR_KEY',\n  googleSenderId: 'YOUR_SENDER',\n  useUsServer: true,\n}]\n```\n\nFor a custom URL (overrides `useUsServer`):\n\n```js\nserverUrl: 'https://sdk.your-tenant.xtremepush.com',\n```\n\nAfter changing server config, run `npx expo prebuild --clean`. Both platforms use the same URL.\n\n### Delivery receipts\n\nTells the dashboard a push was actually delivered (not just sent). Requires Android SDK ≥ 7.9.0 ([`XP_W001`](#xp_w001) below that). On iOS the feature is supported by every SDK version this plugin pins — the default `iosSdkVersion` is `'6.1'` — so no version action is needed there.\n\n```js\n['xtremepush-expo-plugin', {\n  applicationKey: 'YOUR_KEY',\n  googleSenderId: 'YOUR_SENDER',\n  enableDeliveryReceipts: true,\n  iosAppGroupIdentifier: 'group.com.yourcompany.yourapp.xtremepush.suit',\n  devTeam: 'ABCDE12345',\n}]\n```\n\nWhat the plugin generates:\n- **iOS:** `XPush.setDeliveryReceiptsEnabled(true)`, `XPush.enableAppGroups(...)`, `application(_:didReceiveRemoteNotification:fetchCompletionHandler:)` injected into AppDelegate. The Notification Service Extension is created with its `init()` configured per the XtremePush iOS Enterprise Push docs.\n- **Android:** `.setDeliveryReceiptsEnabled(true)` added to the `PushConnector.Builder` chain in `MainApplication`.\n\nAfter enabling, send a test push and watch the device log for:\n\n```\n[XPush] - userNotificationCenter willPresentNotification: { ... \"delivery-receipt\" = 1 ... }\n[XPush] - Send request: https://sdk.<tenant>.xtremepush.com/push/api/actionHit ...\n[XPush] - Request finished with api: .../actionHit ... code = 200; success = 1;\n```\n\nThe campaign should transition Sent → Delivered in the dashboard within seconds.\n\n### Encrypted push\n\n#### iOS\n\n```js\nenableEncryptedPush: true\n```\n\nInjects `XPush.enableEncryptedPush()` (Swift) or `[XPush enableEncryptedPush]` (Obj-C) into the AppDelegate `setAppKey` block. Both forms are argumentless from iOS SDK 6.1.0+.\n\n#### Android\n\n```js\nenableEncryptedMessages: true\n```\n\nInjects `.setEncryptedMessagesEnabled(true)` into the builder chain. Requires Android SDK ≥ 8.1.0.\n\n#### Dashboard step (both platforms)\n\nUpload your public encryption key in the XtremePush dashboard before enabling. Without it the SDK silently drops decryption attempts on incoming pushes.\n\n#### Receiving deeplinks with encrypted push (cold start)\n\nWhen encrypted push is on, notification content fields — `title`, `text`, `deeplink`, and `data` — travel encrypted and are only readable **after** the SDK decrypts them. That changes how you must read a deeplink on every launch path, including **cold start** (app launched from a killed state by a notification tap).\n\n##### Which API to use\n\n| API | What it returns | Use for encrypted-push deeplink? |\n|---|---|---|\n| **`onDeeplinkReceived`** | SDK **decrypted** deeplink URL | **Yes — required** |\n| **`onMessageResponse`** | SDK **decrypted** message + response (title, text, data, deeplink, …) | Yes, when you need full content |\n| **`getInitialNotification()`** | Raw OS **transport** payload (may still be ciphertext) | **No** for deeplink / content under encryption |\n\nDo **not** fall back to `getInitialNotification()` for navigation under encrypted push. Even when it returns a `deeplink` field, that value may be encrypted garbage. The listener path is cold-start-safe from **1.3.4** (buffer-and-replay hardened; first introduced in 1.3.3).\n\n##### Setup checklist\n\nAll of the following must be true:\n\n1. **Plugin config** — set the event name(s). Without `deeplinkCallback` the native path is a no-op:\n\n   ```json\n   {\n     \"plugins\": [\n       [\n         \"xtremepush-expo-plugin\",\n         {\n           \"applicationKey\": \"YOUR_KEY\",\n           \"googleSenderId\": \"YOUR_SENDER_ID\",\n           \"enableEncryptedPush\": true,\n           \"enableEncryptedMessages\": true,\n           \"deeplinkCallback\": \"onDeeplinkReceived\",\n           \"messageResponseCallback\": \"onMessageResponse\"\n         }\n       ]\n     ]\n   }\n   ```\n\n   Use the same string i","readmeFilename":"README.md"}