@juspay/shooter 1.24.1 → 1.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/.claude/hooks/notifier.cjs +32 -4
  2. package/bin/lib/service-manager.cjs +148 -0
  3. package/bin/shooter.cjs +151 -62
  4. package/build/client/_app/immutable/assets/{4.D4EDSN4H.css → 4.ChO_hlLs.css} +1 -1
  5. package/build/client/_app/immutable/assets/4.ChO_hlLs.css.br +0 -0
  6. package/build/client/_app/immutable/assets/4.ChO_hlLs.css.gz +0 -0
  7. package/build/client/_app/immutable/chunks/{DjWRwZyr.js → BstJSK2K.js} +1 -1
  8. package/build/client/_app/immutable/chunks/BstJSK2K.js.br +0 -0
  9. package/build/client/_app/immutable/chunks/BstJSK2K.js.gz +0 -0
  10. package/build/client/_app/immutable/chunks/{CfzjLyJm.js → DINqYbXU.js} +1 -1
  11. package/build/client/_app/immutable/chunks/DINqYbXU.js.br +0 -0
  12. package/build/client/_app/immutable/chunks/DINqYbXU.js.gz +0 -0
  13. package/build/client/_app/immutable/chunks/ssAhjWfF.js +3 -0
  14. package/build/client/_app/immutable/chunks/ssAhjWfF.js.br +0 -0
  15. package/build/client/_app/immutable/chunks/ssAhjWfF.js.gz +0 -0
  16. package/build/client/_app/immutable/entry/{app.9F0rhLIY.js → app.BPK9s2o5.js} +2 -2
  17. package/build/client/_app/immutable/entry/app.BPK9s2o5.js.br +0 -0
  18. package/build/client/_app/immutable/entry/app.BPK9s2o5.js.gz +0 -0
  19. package/build/client/_app/immutable/entry/start.DFPHuGE3.js +1 -0
  20. package/build/client/_app/immutable/entry/start.DFPHuGE3.js.br +2 -0
  21. package/build/client/_app/immutable/entry/start.DFPHuGE3.js.gz +0 -0
  22. package/build/client/_app/immutable/nodes/{0.MlMcxYLT.js → 0.BEbzRcwm.js} +1 -1
  23. package/build/client/_app/immutable/nodes/0.BEbzRcwm.js.br +0 -0
  24. package/build/client/_app/immutable/nodes/0.BEbzRcwm.js.gz +0 -0
  25. package/build/client/_app/immutable/nodes/{1._Bn-HQ9b.js → 1.C_V0SOr9.js} +1 -1
  26. package/build/client/_app/immutable/nodes/1.C_V0SOr9.js.br +0 -0
  27. package/build/client/_app/immutable/nodes/1.C_V0SOr9.js.gz +0 -0
  28. package/build/client/_app/immutable/nodes/{10.CsX0V4R9.js → 10.6V-37_Rl.js} +1 -1
  29. package/build/client/_app/immutable/nodes/10.6V-37_Rl.js.br +0 -0
  30. package/build/client/_app/immutable/nodes/10.6V-37_Rl.js.gz +0 -0
  31. package/build/client/_app/immutable/nodes/{11.lM_b6yUv.js → 11.Lzf-KC6L.js} +1 -1
  32. package/build/client/_app/immutable/nodes/11.Lzf-KC6L.js.br +0 -0
  33. package/build/client/_app/immutable/nodes/11.Lzf-KC6L.js.gz +0 -0
  34. package/build/client/_app/immutable/nodes/{2.sAnHf5go.js → 2.Cl2dMP2L.js} +1 -1
  35. package/build/client/_app/immutable/nodes/2.Cl2dMP2L.js.br +0 -0
  36. package/build/client/_app/immutable/nodes/2.Cl2dMP2L.js.gz +0 -0
  37. package/build/client/_app/immutable/nodes/{3.DEHWta3G.js → 3.CuX2eSna.js} +1 -1
  38. package/build/client/_app/immutable/nodes/3.CuX2eSna.js.br +0 -0
  39. package/build/client/_app/immutable/nodes/3.CuX2eSna.js.gz +0 -0
  40. package/build/client/_app/immutable/nodes/4.2DvqoOaB.js +17 -0
  41. package/build/client/_app/immutable/nodes/4.2DvqoOaB.js.br +0 -0
  42. package/build/client/_app/immutable/nodes/4.2DvqoOaB.js.gz +0 -0
  43. package/build/client/_app/immutable/nodes/{6.-gDjaLSz.js → 6.C7e6zQyP.js} +1 -1
  44. package/build/client/_app/immutable/nodes/6.C7e6zQyP.js.br +0 -0
  45. package/build/client/_app/immutable/nodes/6.C7e6zQyP.js.gz +0 -0
  46. package/build/client/_app/immutable/nodes/{7.R-emDnvX.js → 7.1ygvNTnO.js} +1 -1
  47. package/build/client/_app/immutable/nodes/7.1ygvNTnO.js.br +0 -0
  48. package/build/client/_app/immutable/nodes/7.1ygvNTnO.js.gz +0 -0
  49. package/build/client/_app/immutable/nodes/{8.DXNcFetv.js → 8.CBVmgOk0.js} +1 -1
  50. package/build/client/_app/immutable/nodes/8.CBVmgOk0.js.br +0 -0
  51. package/build/client/_app/immutable/nodes/8.CBVmgOk0.js.gz +0 -0
  52. package/build/client/_app/immutable/nodes/{9.Brv6N-Ji.js → 9.B-_ZFZhj.js} +1 -1
  53. package/build/client/_app/immutable/nodes/9.B-_ZFZhj.js.br +0 -0
  54. package/build/client/_app/immutable/nodes/9.B-_ZFZhj.js.gz +0 -0
  55. package/build/client/_app/version.json +1 -1
  56. package/build/client/_app/version.json.br +0 -0
  57. package/build/client/_app/version.json.gz +0 -0
  58. package/build/server/chunks/{0-CezVlDLP.js → 0-BHU07xt9.js} +2 -2
  59. package/build/server/chunks/{0-CezVlDLP.js.map → 0-BHU07xt9.js.map} +1 -1
  60. package/build/server/chunks/{1-CAwGzW00.js → 1-OVOd8GUH.js} +2 -2
  61. package/build/server/chunks/{1-CAwGzW00.js.map → 1-OVOd8GUH.js.map} +1 -1
  62. package/build/server/chunks/{10-pqorW2OP.js → 10-CRHtvb_u.js} +2 -2
  63. package/build/server/chunks/{10-pqorW2OP.js.map → 10-CRHtvb_u.js.map} +1 -1
  64. package/build/server/chunks/{11-Byxg_lSY.js → 11-CdSex9j1.js} +2 -2
  65. package/build/server/chunks/{11-Byxg_lSY.js.map → 11-CdSex9j1.js.map} +1 -1
  66. package/build/server/chunks/{2-Bbck5mN2.js → 2-bb78aIZ6.js} +2 -2
  67. package/build/server/chunks/{2-Bbck5mN2.js.map → 2-bb78aIZ6.js.map} +1 -1
  68. package/build/server/chunks/{3-BBFbA1P8.js → 3-CsTC6Lrn.js} +2 -2
  69. package/build/server/chunks/{3-BBFbA1P8.js.map → 3-CsTC6Lrn.js.map} +1 -1
  70. package/build/server/chunks/{4-w2W_T8ax.js → 4-DTTu8_Gr.js} +4 -4
  71. package/build/server/chunks/{4-w2W_T8ax.js.map → 4-DTTu8_Gr.js.map} +1 -1
  72. package/build/server/chunks/{6-BI3p-t3i.js → 6-BUgQGB_4.js} +2 -2
  73. package/build/server/chunks/{6-BI3p-t3i.js.map → 6-BUgQGB_4.js.map} +1 -1
  74. package/build/server/chunks/{7-6XKPVOSu.js → 7-CsQZnkcG.js} +2 -2
  75. package/build/server/chunks/{7-6XKPVOSu.js.map → 7-CsQZnkcG.js.map} +1 -1
  76. package/build/server/chunks/{8-VOztiJG_.js → 8-DcIuPdyW.js} +2 -2
  77. package/build/server/chunks/{8-VOztiJG_.js.map → 8-DcIuPdyW.js.map} +1 -1
  78. package/build/server/chunks/{9-DNUlBLEz.js → 9-D8bkM1uj.js} +2 -2
  79. package/build/server/chunks/{9-DNUlBLEz.js.map → 9-D8bkM1uj.js.map} +1 -1
  80. package/build/server/chunks/{_page.svelte-DDE2nChH.js → _page.svelte-BBbaKwNz.js} +101 -27
  81. package/build/server/chunks/_page.svelte-BBbaKwNz.js.map +1 -0
  82. package/build/server/chunks/{_server.ts-DfscXcFe.js → _server.ts-B7BLxK5u.js} +233 -186
  83. package/build/server/chunks/_server.ts-B7BLxK5u.js.map +1 -0
  84. package/build/server/chunks/{_server.ts-EJVmhLtg.js → _server.ts-BSS8cO80.js} +15 -3
  85. package/build/server/chunks/_server.ts-BSS8cO80.js.map +1 -0
  86. package/build/server/chunks/_server.ts-DNTxPoxO.js +115 -0
  87. package/build/server/chunks/_server.ts-DNTxPoxO.js.map +1 -0
  88. package/build/server/chunks/{_server.ts-D9_hkPQ6.js → _server.ts-DUb7fbuW.js} +17 -3
  89. package/build/server/chunks/_server.ts-DUb7fbuW.js.map +1 -0
  90. package/build/server/chunks/{_server.ts-v7TaT83B.js → _server.ts-FdKi8RwL.js} +7 -3
  91. package/build/server/chunks/_server.ts-FdKi8RwL.js.map +1 -0
  92. package/build/server/chunks/device-format-DTgEz4Yr.js +29 -0
  93. package/build/server/chunks/device-format-DTgEz4Yr.js.map +1 -0
  94. package/build/server/chunks/device-token-store-Ct7aTeR8.js +259 -0
  95. package/build/server/chunks/device-token-store-Ct7aTeR8.js.map +1 -0
  96. package/build/server/chunks/{library-apns-D8RPINlv.js → library-apns-DMlL1BAg.js} +158 -26
  97. package/build/server/chunks/library-apns-DMlL1BAg.js.map +1 -0
  98. package/build/server/index.js +1 -1
  99. package/build/server/index.js.map +1 -1
  100. package/build/server/manifest.js +17 -17
  101. package/build/server/manifest.js.map +1 -1
  102. package/package.json +2 -2
  103. package/server.ts +15 -1
  104. package/src/app.d.ts +4 -0
  105. package/src/lib/modules/server/apn/apns-classify.ts +103 -0
  106. package/src/lib/modules/server/apn/library-apns.ts +151 -35
  107. package/src/lib/modules/server/apn/notify-fanout.ts +40 -0
  108. package/src/lib/modules/server/fcm/fcm-classify.ts +61 -0
  109. package/src/lib/modules/server/fcm/fcm-service.ts +128 -29
  110. package/src/lib/modules/server/push/device-format.ts +42 -0
  111. package/src/lib/modules/server/push/device-token-store.ts +354 -0
  112. package/src/lib/types/apn.ts +4 -0
  113. package/src/lib/types/device.ts +156 -0
  114. package/src/lib/types/index.ts +1 -0
  115. package/src/routes/api/debug/+server.ts +13 -1
  116. package/src/routes/api/device-token/+server.ts +122 -37
  117. package/src/routes/api/health/+server.ts +16 -2
  118. package/src/routes/api/notify/+server.ts +175 -168
  119. package/src/routes/api/qr-config/+server.ts +9 -2
  120. package/src/routes/config/+page.svelte +182 -44
  121. package/build/client/_app/immutable/assets/4.D4EDSN4H.css.br +0 -0
  122. package/build/client/_app/immutable/assets/4.D4EDSN4H.css.gz +0 -0
  123. package/build/client/_app/immutable/chunks/BzW0vlVX.js +0 -3
  124. package/build/client/_app/immutable/chunks/BzW0vlVX.js.br +0 -0
  125. package/build/client/_app/immutable/chunks/BzW0vlVX.js.gz +0 -0
  126. package/build/client/_app/immutable/chunks/CfzjLyJm.js.br +0 -0
  127. package/build/client/_app/immutable/chunks/CfzjLyJm.js.gz +0 -0
  128. package/build/client/_app/immutable/chunks/DjWRwZyr.js.br +0 -0
  129. package/build/client/_app/immutable/chunks/DjWRwZyr.js.gz +0 -0
  130. package/build/client/_app/immutable/entry/app.9F0rhLIY.js.br +0 -0
  131. package/build/client/_app/immutable/entry/app.9F0rhLIY.js.gz +0 -0
  132. package/build/client/_app/immutable/entry/start.DGFWmhrj.js +0 -1
  133. package/build/client/_app/immutable/entry/start.DGFWmhrj.js.br +0 -2
  134. package/build/client/_app/immutable/entry/start.DGFWmhrj.js.gz +0 -0
  135. package/build/client/_app/immutable/nodes/0.MlMcxYLT.js.br +0 -0
  136. package/build/client/_app/immutable/nodes/0.MlMcxYLT.js.gz +0 -0
  137. package/build/client/_app/immutable/nodes/1._Bn-HQ9b.js.br +0 -0
  138. package/build/client/_app/immutable/nodes/1._Bn-HQ9b.js.gz +0 -0
  139. package/build/client/_app/immutable/nodes/10.CsX0V4R9.js.br +0 -0
  140. package/build/client/_app/immutable/nodes/10.CsX0V4R9.js.gz +0 -0
  141. package/build/client/_app/immutable/nodes/11.lM_b6yUv.js.br +0 -0
  142. package/build/client/_app/immutable/nodes/11.lM_b6yUv.js.gz +0 -0
  143. package/build/client/_app/immutable/nodes/2.sAnHf5go.js.br +0 -0
  144. package/build/client/_app/immutable/nodes/2.sAnHf5go.js.gz +0 -0
  145. package/build/client/_app/immutable/nodes/3.DEHWta3G.js.br +0 -0
  146. package/build/client/_app/immutable/nodes/3.DEHWta3G.js.gz +0 -0
  147. package/build/client/_app/immutable/nodes/4.C9fv_m2R.js +0 -16
  148. package/build/client/_app/immutable/nodes/4.C9fv_m2R.js.br +0 -0
  149. package/build/client/_app/immutable/nodes/4.C9fv_m2R.js.gz +0 -0
  150. package/build/client/_app/immutable/nodes/6.-gDjaLSz.js.br +0 -0
  151. package/build/client/_app/immutable/nodes/6.-gDjaLSz.js.gz +0 -0
  152. package/build/client/_app/immutable/nodes/7.R-emDnvX.js.br +0 -0
  153. package/build/client/_app/immutable/nodes/7.R-emDnvX.js.gz +0 -0
  154. package/build/client/_app/immutable/nodes/8.DXNcFetv.js.br +0 -0
  155. package/build/client/_app/immutable/nodes/8.DXNcFetv.js.gz +0 -0
  156. package/build/client/_app/immutable/nodes/9.Brv6N-Ji.js.br +0 -0
  157. package/build/client/_app/immutable/nodes/9.Brv6N-Ji.js.gz +0 -0
  158. package/build/server/chunks/_page.svelte-DDE2nChH.js.map +0 -1
  159. package/build/server/chunks/_server.ts-D2RS8TFd.js +0 -72
  160. package/build/server/chunks/_server.ts-D2RS8TFd.js.map +0 -1
  161. package/build/server/chunks/_server.ts-D9_hkPQ6.js.map +0 -1
  162. package/build/server/chunks/_server.ts-DfscXcFe.js.map +0 -1
  163. package/build/server/chunks/_server.ts-EJVmhLtg.js.map +0 -1
  164. package/build/server/chunks/_server.ts-v7TaT83B.js.map +0 -1
  165. package/build/server/chunks/library-apns-D8RPINlv.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_server.ts-B7BLxK5u.js","sources":["../../../.svelte-kit/adapter-node/entries/endpoints/api/notify/_server.ts.js"],"sourcesContent":["import { b as private_env } from \"../../../../chunks/shared-server.js\";\nimport { L as LibraryAPNsService } from \"../../../../chunks/library-apns.js\";\nimport { c as createPendingRequest } from \"../../../../chunks/pending-requests.js\";\nimport { v as validateAuth } from \"../../../../chunks/auth.js\";\nimport admin from \"firebase-admin\";\nimport { m as maskToken } from \"../../../../chunks/device-format.js\";\nimport { d as deviceTokenStore } from \"../../../../chunks/device-token-store.js\";\nimport { t as toErrorMessage } from \"../../../../chunks/error.js\";\nimport { b as broadcastEvent } from \"../../../../chunks/guest-registry.js\";\nimport \"../../../../chunks/super-session-handler.js\";\nimport { json } from \"@sveltejs/kit\";\nconst MAX_HISTORY = 100;\nconst history = [];\nfunction addNotification(record) {\n history.unshift(record);\n if (history.length > MAX_HISTORY) {\n history.length = MAX_HISTORY;\n }\n}\nfunction getNotifications(limit = 50) {\n return history.slice(0, limit);\n}\nfunction selectPlatforms(platformFilter) {\n if (platformFilter === \"ios\") {\n return { doAndroid: false, doIos: true };\n }\n if (platformFilter === \"android\") {\n return { doAndroid: true, doIos: false };\n }\n return { doAndroid: true, doIos: true };\n}\nfunction summarizeNotifyDelivery(apns, fcm) {\n const sent = apns.totalSent + fcm.successCount;\n const failed = apns.totalFailed + fcm.failureCount;\n const staleTokens = [...apns.staleTokens, ...fcm.staleTokens];\n const succeededTokens = [\n ...apns.results.filter((r) => r.success).map((r) => r.token),\n ...fcm.results.filter((r) => r.success).map((r) => r.token)\n ];\n return { delivered: sent > 0, failed, sent, staleTokens, succeededTokens };\n}\nconst PRUNABLE_FCM_CODES = /* @__PURE__ */ new Set([\n \"messaging/registration-token-not-registered\"\n]);\nfunction chunk(items, size) {\n const out = [];\n for (let i = 0; i < items.length; i += size) {\n out.push(items.slice(i, i + size));\n }\n return out;\n}\nfunction classifyFcmError(code) {\n return code && PRUNABLE_FCM_CODES.has(code) ? \"prune\" : \"keep\";\n}\nfunction summarizeFcmFanOut(outcomes) {\n const results = [];\n const staleTokens = [];\n let successCount = 0;\n let failureCount = 0;\n for (const o of outcomes) {\n if (o.success) {\n successCount += 1;\n } else {\n failureCount += 1;\n if (classifyFcmError(o.errorCode) === \"prune\") {\n staleTokens.push(o.token);\n }\n }\n results.push({\n error: o.errorCode,\n messageId: o.messageId,\n success: o.success,\n token: o.token\n });\n }\n return { failureCount, results, staleTokens, successCount };\n}\nlet app = null;\nconst FCM_MULTICAST_CHUNK = 100;\nfunction isFCMConfigured() {\n return !!(process.env.FCM_PROJECT_ID && process.env.FCM_CLIENT_EMAIL && process.env.FCM_PRIVATE_KEY);\n}\nasync function sendFCMNotificationMulti(tokens, payload) {\n if (tokens.length === 0) {\n return { failureCount: 0, results: [], staleTokens: [], successCount: 0 };\n }\n let fcmApp;\n try {\n fcmApp = getApp();\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n console.error(\"[FCM] multi-send setup failed:\", fcmErrorLabel(error));\n return {\n failureCount: tokens.length,\n results: tokens.map((token) => ({ error: msg, messageId: null, success: false, token })),\n staleTokens: [],\n successCount: 0\n };\n }\n const base = buildDataMessage(payload);\n const outcomes = [];\n for (const group of chunk(tokens, FCM_MULTICAST_CHUNK)) {\n try {\n const batch = await admin.messaging(fcmApp).sendEachForMulticast({ ...base, tokens: [...group] });\n batch.responses.forEach((resp, i) => {\n const errorCode = resp.error?.code ?? null;\n if (errorCode === \"messaging/invalid-argument\") {\n console.error(`[FCM] invalid-argument for token ${maskToken(group[i])}: ${errorCode}`);\n }\n outcomes.push({\n errorCode,\n messageId: resp.messageId ?? null,\n success: resp.success,\n token: group[i]\n });\n });\n } catch (error) {\n console.error(\"[FCM] multicast chunk failed:\", fcmErrorLabel(error));\n for (const token of group) {\n outcomes.push({ errorCode: null, messageId: null, success: false, token });\n }\n }\n }\n return summarizeFcmFanOut(outcomes);\n}\nfunction buildDataMessage(payload) {\n return {\n android: {\n priority: \"high\",\n // Ensures delivery even in Doze mode\n ttl: 3e5\n // 5 minutes TTL (matches pending request expiry)\n },\n data: {\n body: payload.body || payload.message || \"\",\n category: payload.category ?? (typeof payload.data?.category === \"string\" ? payload.data.category : \"\"),\n project: typeof payload.data?.project === \"string\" ? payload.data.project : \"\",\n requestId: typeof payload.data?.requestId === \"string\" ? payload.data.requestId : \"\",\n source: typeof payload.data?.source === \"string\" ? payload.data.source : \"\",\n subtitle: payload.subtitle ?? \"\",\n timestamp: (/* @__PURE__ */ new Date()).toISOString(),\n title: payload.title,\n toolInput: payload.data?.toolInput ? JSON.stringify(payload.data.toolInput) : \"\",\n toolName: typeof payload.data?.toolName === \"string\" ? payload.data.toolName : \"\",\n type: typeof payload.data?.type === \"string\" ? payload.data.type : \"\"\n }\n };\n}\nfunction fcmErrorLabel(error) {\n if (error && typeof error === \"object\" && \"code\" in error) {\n const code = error.code;\n if (typeof code === \"string\" && code.length > 0) {\n return code;\n }\n }\n return error instanceof Error ? error.message : String(error);\n}\nfunction getApp() {\n if (!app) {\n const projectId = process.env.FCM_PROJECT_ID;\n const clientEmail = process.env.FCM_CLIENT_EMAIL;\n const privateKey = process.env.FCM_PRIVATE_KEY?.replace(/\\\\n/g, \"\\n\");\n if (!projectId || !clientEmail || !privateKey) {\n throw new Error(\n \"FCM not configured: missing FCM_PROJECT_ID, FCM_CLIENT_EMAIL, or FCM_PRIVATE_KEY\"\n );\n }\n app = admin.initializeApp({\n credential: admin.credential.cert({ clientEmail, privateKey, projectId })\n });\n }\n return app;\n}\nlet apnsSingleton = null;\nfunction getAPNsClient() {\n if (!apnsSingleton) {\n apnsSingleton = new LibraryAPNsService();\n }\n return apnsSingleton;\n}\nconst EMPTY_APNS_RESULT = {\n results: [],\n staleTokens: [],\n totalFailed: 0,\n totalSent: 0\n};\nconst EMPTY_FCM_RESULT = {\n failureCount: 0,\n results: [],\n staleTokens: [],\n successCount: 0\n};\nfunction resolveAndroidTokens() {\n const rows = deviceTokenStore.listActive(\"android\");\n if (rows.length > 0) {\n return rows.map((r) => r.token);\n }\n const seed = private_env.ANDROID_DEVICE_TOKEN?.trim();\n return seed ? [seed] : [];\n}\nfunction resolveIosDevices(override) {\n const appEnv = serverApnEnv();\n if (override) {\n return [syntheticSeedDevice(override, \"ios\", appEnv)];\n }\n const rows = deviceTokenStore.listActiveForEnv(\"ios\", appEnv);\n if (rows.length > 0) {\n return rows;\n }\n const seed = private_env.DEVICE_TOKEN?.trim();\n return seed ? [syntheticSeedDevice(seed, \"ios\", appEnv)] : [];\n}\nfunction serverApnEnv() {\n return private_env.APNS_PRODUCTION === \"true\" ? \"production\" : \"sandbox\";\n}\nfunction syntheticSeedDevice(token, platform, appEnv) {\n const nowIso = (/* @__PURE__ */ new Date()).toISOString();\n return {\n appEnv,\n bundleId: null,\n deviceId: null,\n failureCount: 0,\n friendlyName: null,\n id: `seed-${platform}`,\n isActive: true,\n lastSeenAt: nowIso,\n platform,\n registeredAt: nowIso,\n token\n };\n}\nconst notificationCache = /* @__PURE__ */ new Map();\nconst DEDUP_WINDOW = 1e4;\nfunction broadcastHookEvent(body) {\n const data = body.data ?? {};\n const eventType = typeof data.eventType === \"string\" ? data.eventType : typeof body.eventType === \"string\" ? body.eventType : \"\";\n const tool = typeof data.tool === \"string\" ? data.tool : \"\";\n const terminalId = typeof data.terminalId === \"string\" ? data.terminalId : void 0;\n const sessionId = typeof data.sessionId === \"string\" ? data.sessionId : void 0;\n switch (eventType) {\n case \"error\":\n broadcastEvent({\n error: typeof data.error === \"string\" ? data.error : typeof data.message === \"string\" ? data.message : \"Unknown error\",\n terminalId,\n tool,\n type: \"tool-failed\"\n });\n break;\n case \"idle_input\":\n case \"session.idle\":\n broadcastEvent({\n message: typeof data.message === \"string\" ? data.message : \"\",\n sessionId,\n terminalId,\n type: \"agent-idle\"\n });\n break;\n case \"permission\":\n case \"permission_notification\":\n if (data.requestId && data.toolName) {\n broadcastEvent({\n input: typeof data.toolInput === \"object\" && data.toolInput !== null ? data.toolInput : {},\n requestId: data.requestId,\n tool: data.toolName,\n type: \"permission-requested\"\n });\n }\n break;\n case \"question\":\n broadcastEvent({\n message: typeof data.message === \"string\" ? data.message : \"\",\n sessionId,\n terminalId,\n type: \"agent-question\"\n });\n break;\n case \"tool.after\":\n broadcastEvent({ success: true, terminalId, tool, type: \"tool-completed\" });\n break;\n case \"tool.before\":\n broadcastEvent({\n command: typeof data.command === \"string\" ? data.command : \"\",\n filePath: typeof data.filePath === \"string\" ? data.filePath : typeof data.files === \"string\" ? data.files : \"\",\n terminalId,\n tool,\n type: \"tool-started\"\n });\n break;\n }\n}\nfunction buildNotificationRecord(id, title, message, status, data, error) {\n return {\n category: data?.category ?? null,\n data: data ?? null,\n error: error ?? null,\n id,\n message,\n project: data?.project ?? null,\n source: data?.source ?? null,\n status,\n timestamp: (/* @__PURE__ */ new Date()).toISOString(),\n title,\n tool: data?.tool ?? null\n };\n}\nfunction intelligentNotificationFilter(title, message, data, waitForResponse = false) {\n const source = data?.source || \"unknown\";\n if (waitForResponse) {\n return { reason: \"Bidirectional request — never filtered\", send: true };\n }\n if (isDuplicateNotification(title, message, data, waitForResponse)) {\n return {\n reason: \"Duplicate notification within 10-second window\",\n send: false\n };\n }\n if (source === \"smart-completion-detector\" || source === \"shooter-completion-detector\") {\n return {\n reason: \"Smart completion detector - completion or intervention needed\",\n send: true\n };\n }\n const spamPatterns = [\n /PreToolUse/i,\n // Any PreToolUse notifications\n /PostToolUse/i,\n // Any PostToolUse notifications\n /^(Read|Write|Edit|Bash)\\s+Starting\\s*\\|\\s*\\w+$/i,\n // Only basic tool starting patterns\n /^unknown\\s*\\|\\s*\\w+$/i\n // Only \"unknown | projectname\" exactly\n ];\n const isSpam = spamPatterns.some((pattern) => pattern.test(title) || pattern.test(message));\n if (isSpam) {\n return {\n reason: \"Filtered spam notification from old hook system\",\n send: false\n };\n }\n const importantPatterns = [\n /session complete/i,\n /intervention needed/i,\n /error/i,\n /failed/i,\n /blocked/i,\n /attention/i\n ];\n const isImportant = importantPatterns.some(\n (pattern) => pattern.test(title) || pattern.test(message)\n );\n if (isImportant) {\n return {\n reason: \"Important notification - completion or intervention\",\n send: true\n };\n }\n return {\n reason: \"General notification - allowing by default\",\n send: true\n };\n}\nfunction isDuplicateNotification(title, message, data, waitForResponse = false) {\n if (waitForResponse) {\n return false;\n }\n const dataRecord = data;\n const key = dataRecord?.dedupKey ? dataRecord.dedupKey : `${title}|${message}|${data?.category || \"unknown\"}`;\n const now = Date.now();\n if (notificationCache.has(key)) {\n const lastSent = notificationCache.get(key) ?? 0;\n if (now - lastSent < DEDUP_WINDOW) {\n return true;\n }\n }\n for (const [k, v] of notificationCache.entries()) {\n if (now - v > DEDUP_WINDOW) {\n notificationCache.delete(k);\n }\n }\n notificationCache.set(key, now);\n return false;\n}\nfunction notificationKey(title, message, data) {\n const dataRecord = data;\n return dataRecord?.dedupKey ?? `${title}|${message}|${data?.category || \"unknown\"}`;\n}\nfunction recordNotification(title, message, data) {\n notificationCache.set(notificationKey(title, message, data), Date.now());\n}\nfunction releaseNotification(title, message, data) {\n notificationCache.delete(notificationKey(title, message, data));\n}\nconst POST = async ({ request }) => {\n try {\n const apnsClient = getAPNsClient();\n const authError = validateAuth(request);\n if (authError) {\n return authError;\n }\n const rawBody = await request.json();\n if (!rawBody || typeof rawBody !== \"object\" || Array.isArray(rawBody)) {\n return json({ error: \"Request body must be a JSON object\" }, { status: 400 });\n }\n const body = rawBody;\n const data = body.data;\n const requestDeviceToken = body.deviceToken;\n const message = body.message;\n const title = body.title;\n const subtitle = typeof body.subtitle === \"string\" ? body.subtitle : void 0;\n const skipPush = typeof body.skipPush === \"boolean\" ? body.skipPush : false;\n const waitForResponse = typeof body.waitForResponse === \"boolean\" ? body.waitForResponse : false;\n const forcePush = typeof body.forcePush === \"boolean\" ? body.forcePush : false;\n const notificationCategory = typeof body.notificationCategory === \"string\" && body.notificationCategory.length > 0 ? body.notificationCategory : void 0;\n const question = typeof body.question === \"string\" ? body.question : void 0;\n const options = Array.isArray(body.options) && body.options.every((o) => o && typeof o === \"object\") ? body.options : void 0;\n const responseKindRaw = body.responseKind;\n const responseKind = responseKindRaw === \"hook\" || responseKindRaw === \"pty\" || responseKindRaw === \"info\" ? responseKindRaw : void 0;\n try {\n broadcastHookEvent(body);\n } catch {\n }\n if (!title || typeof title !== \"string\" || !message || typeof message !== \"string\") {\n return json({ error: \"Title and message are required and must be strings\" }, { status: 400 });\n }\n if (requestDeviceToken !== void 0 && typeof requestDeviceToken !== \"string\") {\n return json({ error: \"deviceToken must be a string\" }, { status: 400 });\n }\n const requestId = Math.random().toString(36).substring(2, 15);\n const dataRequestId = typeof data?.requestId === \"string\" ? data.requestId : void 0;\n const canonicalRequestId = dataRequestId || requestId;\n const shouldSendNotification = intelligentNotificationFilter(\n title,\n message,\n data,\n waitForResponse\n );\n if (!shouldSendNotification.send) {\n addNotification(\n buildNotificationRecord(\n canonicalRequestId,\n title,\n message,\n \"filtered\",\n data,\n shouldSendNotification.reason\n )\n );\n return json({\n message: \"Notification filtered (not sent)\",\n reason: shouldSendNotification.reason,\n success: true,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n }\n if (skipPush && !forcePush) {\n if (waitForResponse) {\n createPendingRequest(canonicalRequestId, {\n options,\n question: question ?? null,\n responseKind: responseKind ?? \"hook\",\n sessionId: data?.sessionId || \"\",\n toolInput: data?.toolInput || {},\n toolName: data?.toolName || \"\"\n });\n }\n addNotification(buildNotificationRecord(canonicalRequestId, title, message, \"skipped\", data));\n return json({\n message: \"Push skipped (WebSocket clients connected)\",\n requestId: canonicalRequestId,\n success: true,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n }\n const payload = {\n badge: 1,\n body: message,\n // notificationCategory wins when explicitly set so plan-mode /\n // elicitation flows can pick CLAUDE_PLAN_APPROVAL / CHOICE_2..4.\n // Falls back to CLAUDE_PERMISSION for the legacy bidirectional\n // permission flow when only waitForResponse is provided.\n category: notificationCategory ?? (waitForResponse ? \"CLAUDE_PERMISSION\" : void 0),\n data: {\n ...data,\n requestId: canonicalRequestId,\n source: \"modern-apns-api\",\n timestamp: (/* @__PURE__ */ new Date()).toISOString(),\n waitForResponse: waitForResponse || false\n },\n message: null,\n sound: \"default\",\n ...subtitle ? { subtitle } : {},\n title\n };\n const override = requestDeviceToken?.trim() || void 0;\n const { doAndroid, doIos } = selectPlatforms(private_env.DEVICE_PLATFORM);\n const iosDevices = doIos ? override ? resolveIosDevices(override) : resolveIosDevices() : [];\n const androidTokens = doAndroid ? override ? [override] : resolveAndroidTokens() : [];\n const collapseId = waitForResponse ? canonicalRequestId : void 0;\n const [apnsResult, fcmResult] = await Promise.all([\n iosDevices.length > 0 && apnsClient.isConfigured() ? apnsClient.sendToMany(iosDevices, payload, collapseId) : Promise.resolve(EMPTY_APNS_RESULT),\n androidTokens.length > 0 && isFCMConfigured() ? sendFCMNotificationMulti(androidTokens, payload) : Promise.resolve(EMPTY_FCM_RESULT)\n ]);\n const summary = summarizeNotifyDelivery(apnsResult, fcmResult);\n const pruned = !override && summary.staleTokens.length ? deviceTokenStore.pruneByTokens(summary.staleTokens) : 0;\n if (summary.succeededTokens.length > 0) {\n deviceTokenStore.touchLastSeen(summary.succeededTokens);\n }\n if (summary.delivered && summary.failed === 0) {\n recordNotification(title, message, data);\n } else {\n releaseNotification(title, message, data);\n }\n if (waitForResponse && summary.delivered) {\n createPendingRequest(canonicalRequestId, {\n options,\n question: question ?? null,\n responseKind: responseKind ?? \"hook\",\n sessionId: data?.sessionId || \"\",\n toolInput: data?.toolInput || {},\n toolName: data?.toolName || \"\"\n });\n }\n addNotification(\n buildNotificationRecord(\n canonicalRequestId,\n title,\n message,\n summary.delivered ? \"sent\" : \"failed\",\n data,\n summary.delivered ? null : \"No registered device accepted the notification\"\n )\n );\n return json({\n failed: summary.failed,\n pruned,\n requestId: canonicalRequestId,\n sent: summary.sent,\n success: summary.delivered,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n } catch (error) {\n console.error(\"Notification error:\", error);\n return json(\n {\n details: toErrorMessage(error),\n error: \"Failed to send notification\",\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n },\n { status: 500 }\n );\n }\n};\nconst GET = ({ request, url }) => {\n const authError = validateAuth(request);\n if (authError) {\n return authError;\n }\n const limit = parseInt(url.searchParams.get(\"limit\") || \"50\");\n const notifications = getNotifications(limit);\n return json({\n count: notifications.length,\n notifications,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n};\nexport {\n GET,\n POST\n};\n"],"names":[],"mappings":"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"}
@@ -1,12 +1,18 @@
1
1
  import { b as private_env } from './shared-server-DaWdgxVh.js';
2
- import { L as LibraryAPNsService } from './library-apns-D8RPINlv.js';
2
+ import { L as LibraryAPNsService } from './library-apns-DMlL1BAg.js';
3
3
  import { v as validateAuth } from './auth-DuunT7Cg.js';
4
+ import { d as deviceTokenStore } from './device-token-store-Ct7aTeR8.js';
4
5
  import { j as json } from './index-lhTMmBNn.js';
5
6
  import 'child_process';
6
7
  import 'jsonwebtoken';
7
8
  import 'util';
8
9
  import './error-DDXB3duW.js';
9
10
  import 'crypto';
11
+ import 'better-sqlite3';
12
+ import 'fs';
13
+ import 'path';
14
+ import './shooter-home-4f_HkdGI.js';
15
+ import 'os';
10
16
 
11
17
  const GET = ({ request }) => {
12
18
  const authError = validateAuth(request);
@@ -14,7 +20,9 @@ const GET = ({ request }) => {
14
20
  return authError;
15
21
  }
16
22
  const apnsClient = new LibraryAPNsService();
17
- const deviceToken = private_env.DEVICE_TOKEN?.trim();
23
+ const apnsEnv = private_env.APNS_PRODUCTION === "true" ? "production" : "sandbox";
24
+ const iosDevices = deviceTokenStore.listActiveForEnv("ios", apnsEnv);
25
+ const deviceToken = iosDevices[0]?.token ?? private_env.DEVICE_TOKEN?.trim() ?? "";
18
26
  return json({
19
27
  apns: {
20
28
  configured: apnsClient.isConfigured(),
@@ -31,9 +39,13 @@ const GET = ({ request }) => {
31
39
  },
32
40
  environment: private_env.NODE_ENV || "development",
33
41
  hasApiKey: !!private_env.API_KEY,
42
+ registeredDevices: {
43
+ android: deviceTokenStore.listActive("android").length,
44
+ ios: iosDevices.length
45
+ },
34
46
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
35
47
  });
36
48
  };
37
49
 
38
50
  export { GET };
39
- //# sourceMappingURL=_server.ts-EJVmhLtg.js.map
51
+ //# sourceMappingURL=_server.ts-BSS8cO80.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_server.ts-BSS8cO80.js","sources":["../../../.svelte-kit/adapter-node/entries/endpoints/api/debug/_server.ts.js"],"sourcesContent":["import { b as private_env } from \"../../../../chunks/shared-server.js\";\nimport { L as LibraryAPNsService } from \"../../../../chunks/library-apns.js\";\nimport { v as validateAuth } from \"../../../../chunks/auth.js\";\nimport { d as deviceTokenStore } from \"../../../../chunks/device-token-store.js\";\nimport { json } from \"@sveltejs/kit\";\nconst GET = ({ request }) => {\n const authError = validateAuth(request);\n if (authError) {\n return authError;\n }\n const apnsClient = new LibraryAPNsService();\n const apnsEnv = private_env.APNS_PRODUCTION === \"true\" ? \"production\" : \"sandbox\";\n const iosDevices = deviceTokenStore.listActiveForEnv(\"ios\", apnsEnv);\n const deviceToken = iosDevices[0]?.token ?? private_env.DEVICE_TOKEN?.trim() ?? \"\";\n return json({\n apns: {\n configured: apnsClient.isConfigured(),\n environment: private_env.APNS_PRODUCTION === \"true\" ? \"production\" : \"sandbox\",\n hasBundleId: !!private_env.APNS_BUNDLE_ID,\n hasKey: !!private_env.APNS_KEY,\n hasKeyId: !!private_env.APNS_KEY_ID,\n hasTeamId: !!private_env.APNS_TEAM_ID\n },\n deviceToken: {\n exists: !!deviceToken,\n length: deviceToken ? deviceToken.length : 0,\n valid: deviceToken ? /^[a-f0-9]{64}$/i.test(deviceToken) : false\n },\n environment: private_env.NODE_ENV || \"development\",\n hasApiKey: !!private_env.API_KEY,\n registeredDevices: {\n android: deviceTokenStore.listActive(\"android\").length,\n ios: iosDevices.length\n },\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n};\nexport {\n GET\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAKK,MAAC,GAAG,GAAG,CAAC,EAAE,OAAO,EAAE,KAAK;AAC7B,EAAE,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC;AACzC,EAAE,IAAI,SAAS,EAAE;AACjB,IAAI,OAAO,SAAS;AACpB,EAAE;AACF,EAAE,MAAM,UAAU,GAAG,IAAI,kBAAkB,EAAE;AAC7C,EAAE,MAAM,OAAO,GAAG,WAAW,CAAC,eAAe,KAAK,MAAM,GAAG,YAAY,GAAG,SAAS;AACnF,EAAE,MAAM,UAAU,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC;AACtE,EAAE,MAAM,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,WAAW,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE;AACpF,EAAE,OAAO,IAAI,CAAC;AACd,IAAI,IAAI,EAAE;AACV,MAAM,UAAU,EAAE,UAAU,CAAC,YAAY,EAAE;AAC3C,MAAM,WAAW,EAAE,WAAW,CAAC,eAAe,KAAK,MAAM,GAAG,YAAY,GAAG,SAAS;AACpF,MAAM,WAAW,EAAE,CAAC,CAAC,WAAW,CAAC,cAAc;AAC/C,MAAM,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC,QAAQ;AACpC,MAAM,QAAQ,EAAE,CAAC,CAAC,WAAW,CAAC,WAAW;AACzC,MAAM,SAAS,EAAE,CAAC,CAAC,WAAW,CAAC;AAC/B,KAAK;AACL,IAAI,WAAW,EAAE;AACjB,MAAM,MAAM,EAAE,CAAC,CAAC,WAAW;AAC3B,MAAM,MAAM,EAAE,WAAW,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC;AAClD,MAAM,KAAK,EAAE,WAAW,GAAG,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG;AACjE,KAAK;AACL,IAAI,WAAW,EAAE,WAAW,CAAC,QAAQ,IAAI,aAAa;AACtD,IAAI,SAAS,EAAE,CAAC,CAAC,WAAW,CAAC,OAAO;AACpC,IAAI,iBAAiB,EAAE;AACvB,MAAM,OAAO,EAAE,gBAAgB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,MAAM;AAC5D,MAAM,GAAG,EAAE,UAAU,CAAC;AACtB,KAAK;AACL,IAAI,SAAS,EAAE,iBAAiB,IAAI,IAAI,EAAE,EAAE,WAAW;AACvD,GAAG,CAAC;AACJ;;;;"}
@@ -0,0 +1,115 @@
1
+ import { b as private_env } from './shared-server-DaWdgxVh.js';
2
+ import { v as validateAuth } from './auth-DuunT7Cg.js';
3
+ import { t as toDeviceListItem } from './device-format-DTgEz4Yr.js';
4
+ import { d as deviceTokenStore, M as MAX_TOKEN_LENGTH, a as MAX_DEVICE_ID_LENGTH, b as MAX_NAME_LENGTH, c as MAX_BUNDLE_ID_LENGTH } from './device-token-store-Ct7aTeR8.js';
5
+ import { j as json } from './index-lhTMmBNn.js';
6
+ import 'crypto';
7
+ import 'better-sqlite3';
8
+ import 'fs';
9
+ import 'path';
10
+ import './shooter-home-4f_HkdGI.js';
11
+ import 'os';
12
+
13
+ function resolveAppEnv(requested) {
14
+ if (requested === "production" || requested === "sandbox") {
15
+ return requested;
16
+ }
17
+ return private_env.APNS_PRODUCTION === "true" ? "production" : "sandbox";
18
+ }
19
+ const GET = ({ request }) => {
20
+ const authError = validateAuth(request);
21
+ if (authError) {
22
+ return authError;
23
+ }
24
+ const ios = deviceTokenStore.listActive("ios");
25
+ const android = deviceTokenStore.listActive("android");
26
+ const devices = [...ios, ...android].map(toDeviceListItem);
27
+ return json({
28
+ counts: { android: android.length, ios: ios.length, total: devices.length },
29
+ devices
30
+ });
31
+ };
32
+ const DELETE = async ({ request }) => {
33
+ const authError = validateAuth(request);
34
+ if (authError) {
35
+ return authError;
36
+ }
37
+ let body;
38
+ try {
39
+ body = await request.json();
40
+ } catch {
41
+ return json({ error: "Invalid JSON body" }, { status: 400 });
42
+ }
43
+ const id = body && typeof body === "object" && !Array.isArray(body) ? body.id : void 0;
44
+ if (typeof id !== "string" || id.trim().length === 0) {
45
+ return json({ error: "Missing required field: id" }, { status: 400 });
46
+ }
47
+ const removed = deviceTokenStore.deleteById(id.trim());
48
+ if (removed === 0) {
49
+ return json({ error: "Device not found or already removed", id: id.trim() }, { status: 404 });
50
+ }
51
+ return json({ removed, success: true });
52
+ };
53
+ const POST = async ({ request }) => {
54
+ const authError = validateAuth(request);
55
+ if (authError) {
56
+ return authError;
57
+ }
58
+ let body;
59
+ try {
60
+ const parsed = await request.json();
61
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
62
+ return json({ error: "Invalid JSON body: expected an object" }, { status: 400 });
63
+ }
64
+ body = parsed;
65
+ } catch {
66
+ return json({ error: "Invalid JSON body" }, { status: 400 });
67
+ }
68
+ const platform = body.platform;
69
+ if (!platform || platform !== "ios" && platform !== "android") {
70
+ return json(
71
+ { error: 'Missing or invalid platform (must be "ios" or "android")' },
72
+ { status: 400 }
73
+ );
74
+ }
75
+ const rawToken = body.deviceToken || body.token;
76
+ if (!rawToken || typeof rawToken !== "string" || rawToken.trim().length === 0) {
77
+ return json({ error: "Missing device token (deviceToken or token)" }, { status: 400 });
78
+ }
79
+ const token = rawToken.trim();
80
+ const deviceId = typeof body.deviceId === "string" ? body.deviceId.trim() || null : null;
81
+ const friendlyName = typeof body.deviceName === "string" ? body.deviceName.trim() || null : null;
82
+ const bundleId = typeof body.bundleId === "string" ? body.bundleId.trim() || null : null;
83
+ const tooLong = token.length > MAX_TOKEN_LENGTH ? "token" : deviceId && deviceId.length > MAX_DEVICE_ID_LENGTH ? "deviceId" : friendlyName && friendlyName.length > MAX_NAME_LENGTH ? "deviceName" : bundleId && bundleId.length > MAX_BUNDLE_ID_LENGTH ? "bundleId" : null;
84
+ if (tooLong) {
85
+ return json({ error: `Field "${tooLong}" exceeds maximum allowed length` }, { status: 400 });
86
+ }
87
+ const appEnv = resolveAppEnv(body.appEnv);
88
+ const record = deviceTokenStore.upsert({
89
+ appEnv,
90
+ bundleId,
91
+ deviceId,
92
+ friendlyName,
93
+ platform,
94
+ token
95
+ });
96
+ if (record.deviceId !== deviceId) {
97
+ return json(
98
+ { error: "Token is already registered to a different active device" },
99
+ { status: 409 }
100
+ );
101
+ }
102
+ console.log(
103
+ `[device-token] Registered ${platform} device ${record.id} (token len ${token.length})`
104
+ );
105
+ return json({
106
+ deviceId: record.deviceId,
107
+ id: record.id,
108
+ platform,
109
+ success: true,
110
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
111
+ });
112
+ };
113
+
114
+ export { DELETE, GET, POST };
115
+ //# sourceMappingURL=_server.ts-DNTxPoxO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_server.ts-DNTxPoxO.js","sources":["../../../.svelte-kit/adapter-node/entries/endpoints/api/device-token/_server.ts.js"],"sourcesContent":["import { b as private_env } from \"../../../../chunks/shared-server.js\";\nimport { v as validateAuth } from \"../../../../chunks/auth.js\";\nimport { t as toDeviceListItem } from \"../../../../chunks/device-format.js\";\nimport { d as deviceTokenStore, M as MAX_TOKEN_LENGTH, a as MAX_DEVICE_ID_LENGTH, b as MAX_NAME_LENGTH, c as MAX_BUNDLE_ID_LENGTH } from \"../../../../chunks/device-token-store.js\";\nimport { json } from \"@sveltejs/kit\";\nfunction resolveAppEnv(requested) {\n if (requested === \"production\" || requested === \"sandbox\") {\n return requested;\n }\n return private_env.APNS_PRODUCTION === \"true\" ? \"production\" : \"sandbox\";\n}\nconst GET = ({ request }) => {\n const authError = validateAuth(request);\n if (authError) {\n return authError;\n }\n const ios = deviceTokenStore.listActive(\"ios\");\n const android = deviceTokenStore.listActive(\"android\");\n const devices = [...ios, ...android].map(toDeviceListItem);\n return json({\n counts: { android: android.length, ios: ios.length, total: devices.length },\n devices\n });\n};\nconst DELETE = async ({ request }) => {\n const authError = validateAuth(request);\n if (authError) {\n return authError;\n }\n let body;\n try {\n body = await request.json();\n } catch {\n return json({ error: \"Invalid JSON body\" }, { status: 400 });\n }\n const id = body && typeof body === \"object\" && !Array.isArray(body) ? body.id : void 0;\n if (typeof id !== \"string\" || id.trim().length === 0) {\n return json({ error: \"Missing required field: id\" }, { status: 400 });\n }\n const removed = deviceTokenStore.deleteById(id.trim());\n if (removed === 0) {\n return json({ error: \"Device not found or already removed\", id: id.trim() }, { status: 404 });\n }\n return json({ removed, success: true });\n};\nconst POST = async ({ request }) => {\n const authError = validateAuth(request);\n if (authError) {\n return authError;\n }\n let body;\n try {\n const parsed = await request.json();\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return json({ error: \"Invalid JSON body: expected an object\" }, { status: 400 });\n }\n body = parsed;\n } catch {\n return json({ error: \"Invalid JSON body\" }, { status: 400 });\n }\n const platform = body.platform;\n if (!platform || platform !== \"ios\" && platform !== \"android\") {\n return json(\n { error: 'Missing or invalid platform (must be \"ios\" or \"android\")' },\n { status: 400 }\n );\n }\n const rawToken = body.deviceToken || body.token;\n if (!rawToken || typeof rawToken !== \"string\" || rawToken.trim().length === 0) {\n return json({ error: \"Missing device token (deviceToken or token)\" }, { status: 400 });\n }\n const token = rawToken.trim();\n const deviceId = typeof body.deviceId === \"string\" ? body.deviceId.trim() || null : null;\n const friendlyName = typeof body.deviceName === \"string\" ? body.deviceName.trim() || null : null;\n const bundleId = typeof body.bundleId === \"string\" ? body.bundleId.trim() || null : null;\n const tooLong = token.length > MAX_TOKEN_LENGTH ? \"token\" : deviceId && deviceId.length > MAX_DEVICE_ID_LENGTH ? \"deviceId\" : friendlyName && friendlyName.length > MAX_NAME_LENGTH ? \"deviceName\" : bundleId && bundleId.length > MAX_BUNDLE_ID_LENGTH ? \"bundleId\" : null;\n if (tooLong) {\n return json({ error: `Field \"${tooLong}\" exceeds maximum allowed length` }, { status: 400 });\n }\n const appEnv = resolveAppEnv(body.appEnv);\n const record = deviceTokenStore.upsert({\n appEnv,\n bundleId,\n deviceId,\n friendlyName,\n platform,\n token\n });\n if (record.deviceId !== deviceId) {\n return json(\n { error: \"Token is already registered to a different active device\" },\n { status: 409 }\n );\n }\n console.log(\n `[device-token] Registered ${platform} device ${record.id} (token len ${token.length})`\n );\n return json({\n deviceId: record.deviceId,\n id: record.id,\n platform,\n success: true,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n};\nexport {\n DELETE,\n GET,\n POST\n};\n"],"names":[],"mappings":"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"}
@@ -1,10 +1,14 @@
1
1
  import { b as private_env } from './shared-server-DaWdgxVh.js';
2
2
  import { v as validateAuth } from './auth-DuunT7Cg.js';
3
+ import { d as deviceTokenStore } from './device-token-store-Ct7aTeR8.js';
3
4
  import { g as getProviderAvailability } from './providers-DtstoHQ0.js';
4
5
  import { j as json } from './index-lhTMmBNn.js';
5
6
  import { readFileSync } from 'fs';
6
7
  import { join } from 'path';
7
8
  import 'crypto';
9
+ import 'better-sqlite3';
10
+ import './shooter-home-4f_HkdGI.js';
11
+ import 'os';
8
12
 
9
13
  const PKG_VERSION = (() => {
10
14
  const root = process.env.SHOOTER_PKG_ROOT || process.cwd();
@@ -26,11 +30,16 @@ const GET = ({ request, url }) => {
26
30
  const hasProjectId = !!private_env.FCM_PROJECT_ID?.trim();
27
31
  const hasClientEmail = !!private_env.FCM_CLIENT_EMAIL?.trim();
28
32
  const hasPrivateKey = !!private_env.FCM_PRIVATE_KEY?.trim();
33
+ const iosDeviceCount = deviceTokenStore.listActive("ios").length;
34
+ const androidDeviceCount = deviceTokenStore.listActive("android").length;
35
+ const registeredDeviceCount = iosDeviceCount + androidDeviceCount;
29
36
  const checks = {
30
37
  hasApiKey: !!private_env.API_KEY?.trim(),
31
38
  hasAPNsConfig: !!(private_env.APNS_KEY_ID?.trim() && private_env.APNS_TEAM_ID?.trim() && private_env.APNS_KEY?.trim()),
32
39
  hasBundleId: !!private_env.APNS_BUNDLE_ID?.trim(),
33
- hasDeviceToken: !!private_env.DEVICE_TOKEN?.trim(),
40
+ // Backward-compat alias: true if any device is registered OR the legacy
41
+ // single-token env var is still set.
42
+ hasDeviceToken: registeredDeviceCount > 0 || !!private_env.DEVICE_TOKEN?.trim() || !!private_env.ANDROID_DEVICE_TOKEN?.trim(),
34
43
  hasFCMConfig: hasProjectId && hasClientEmail && hasPrivateKey
35
44
  };
36
45
  const fcm = {
@@ -51,7 +60,7 @@ const GET = ({ request, url }) => {
51
60
  warnings.push("APNs not configured — iOS push notifications disabled");
52
61
  }
53
62
  if (!checks.hasDeviceToken) {
54
- warnings.push("No device token set — push notifications have no target");
63
+ warnings.push("No devices registered — push notifications have no target");
55
64
  }
56
65
  if (!checks.hasFCMConfig) {
57
66
  warnings.push("FCM not configured — Android push notifications disabled");
@@ -71,6 +80,11 @@ const GET = ({ request, url }) => {
71
80
  },
72
81
  checks,
73
82
  configuration,
83
+ devices: {
84
+ android: androidDeviceCount,
85
+ ios: iosDeviceCount,
86
+ total: registeredDeviceCount
87
+ },
74
88
  environment: private_env.NODE_ENV || "development",
75
89
  status: "healthy",
76
90
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -90,4 +104,4 @@ const GET = ({ request, url }) => {
90
104
  };
91
105
 
92
106
  export { GET };
93
- //# sourceMappingURL=_server.ts-D9_hkPQ6.js.map
107
+ //# sourceMappingURL=_server.ts-DUb7fbuW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_server.ts-DUb7fbuW.js","sources":["../../../.svelte-kit/adapter-node/entries/endpoints/api/health/_server.ts.js"],"sourcesContent":["import { b as private_env } from \"../../../../chunks/shared-server.js\";\nimport { v as validateAuth } from \"../../../../chunks/auth.js\";\nimport { d as deviceTokenStore } from \"../../../../chunks/device-token-store.js\";\nimport { g as getProviderAvailability } from \"../../../../chunks/providers.js\";\nimport { json } from \"@sveltejs/kit\";\nimport { readFileSync } from \"fs\";\nimport { join } from \"path\";\nconst PKG_VERSION = (() => {\n const root = process.env.SHOOTER_PKG_ROOT || process.cwd();\n try {\n const pkg = JSON.parse(readFileSync(join(root, \"package.json\"), \"utf-8\"));\n return pkg.version || \"unknown\";\n } catch {\n return \"unknown\";\n }\n})();\nconst GET = ({ request, url }) => {\n const wantsDetails = url.searchParams.get(\"details\") === \"true\";\n if (wantsDetails) {\n const authError = validateAuth(request);\n if (authError) {\n return authError;\n }\n }\n const hasProjectId = !!private_env.FCM_PROJECT_ID?.trim();\n const hasClientEmail = !!private_env.FCM_CLIENT_EMAIL?.trim();\n const hasPrivateKey = !!private_env.FCM_PRIVATE_KEY?.trim();\n const iosDeviceCount = deviceTokenStore.listActive(\"ios\").length;\n const androidDeviceCount = deviceTokenStore.listActive(\"android\").length;\n const registeredDeviceCount = iosDeviceCount + androidDeviceCount;\n const checks = {\n hasApiKey: !!private_env.API_KEY?.trim(),\n hasAPNsConfig: !!(private_env.APNS_KEY_ID?.trim() && private_env.APNS_TEAM_ID?.trim() && private_env.APNS_KEY?.trim()),\n hasBundleId: !!private_env.APNS_BUNDLE_ID?.trim(),\n // Backward-compat alias: true if any device is registered OR the legacy\n // single-token env var is still set.\n hasDeviceToken: registeredDeviceCount > 0 || !!private_env.DEVICE_TOKEN?.trim() || !!private_env.ANDROID_DEVICE_TOKEN?.trim(),\n hasFCMConfig: hasProjectId && hasClientEmail && hasPrivateKey\n };\n const fcm = {\n configured: hasProjectId && hasClientEmail && hasPrivateKey,\n hasClientEmail,\n hasPrivateKey,\n hasProjectId\n };\n const configuration = {\n apnsKeyId: private_env.APNS_KEY_ID ? `${private_env.APNS_KEY_ID.substring(0, 4)}...` : \"\",\n bundleId: private_env.APNS_BUNDLE_ID || \"\",\n deviceTokenLength: private_env.DEVICE_TOKEN ? private_env.DEVICE_TOKEN.length : 0,\n fcm,\n production: private_env.APNS_PRODUCTION === \"true\"\n };\n const warnings = [];\n if (!checks.hasAPNsConfig || !checks.hasBundleId) {\n warnings.push(\"APNs not configured — iOS push notifications disabled\");\n }\n if (!checks.hasDeviceToken) {\n warnings.push(\"No devices registered — push notifications have no target\");\n }\n if (!checks.hasFCMConfig) {\n warnings.push(\"FCM not configured — Android push notifications disabled\");\n }\n const aiProviders = getProviderAvailability(private_env);\n const hasAnyAiProvider = Object.values(aiProviders).some(Boolean);\n if (!hasAnyAiProvider) {\n warnings.push(\n 'No AI provider configured — AI summaries disabled. Run \"shooter setup\" to configure.'\n );\n }\n const health = {\n ai: {\n activeProvider: private_env.NEUROLINK_PROVIDER ?? \"auto\",\n hasAnyProvider: hasAnyAiProvider,\n providers: aiProviders\n },\n checks,\n configuration,\n devices: {\n android: androidDeviceCount,\n ios: iosDeviceCount,\n total: registeredDeviceCount\n },\n environment: private_env.NODE_ENV || \"development\",\n status: \"healthy\",\n timestamp: (/* @__PURE__ */ new Date()).toISOString(),\n version: PKG_VERSION,\n warnings\n };\n if (!wantsDetails) {\n const publicWarnings = health.warnings.filter((w) => !w.includes(\"AI provider\"));\n return json({\n status: health.status,\n timestamp: health.timestamp,\n version: health.version,\n warnings: publicWarnings\n });\n }\n return json(health);\n};\nexport {\n GET\n};\n"],"names":[],"mappings":"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"}
@@ -14,8 +14,12 @@ const GET = async ({ request, url }) => {
14
14
  if (!apiKey) {
15
15
  return json({ error: "API_KEY not configured on server" }, { status: 500 });
16
16
  }
17
- const serverUrl = private_env.ORIGIN?.trim() || url.origin;
18
- const configPayload = JSON.stringify({ apiKey, serverUrl });
17
+ const serverUrl = (private_env.ORIGIN?.trim() || url.origin).replace(/\/+$/, "");
18
+ const configPayload = JSON.stringify({
19
+ apiKey,
20
+ registerUrl: `${serverUrl}/api/device-token`,
21
+ serverUrl
22
+ });
19
23
  try {
20
24
  const dataUrl = await QRCode.toDataURL(configPayload, {
21
25
  color: {
@@ -35,4 +39,4 @@ const GET = async ({ request, url }) => {
35
39
  };
36
40
 
37
41
  export { GET };
38
- //# sourceMappingURL=_server.ts-v7TaT83B.js.map
42
+ //# sourceMappingURL=_server.ts-FdKi8RwL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_server.ts-FdKi8RwL.js","sources":["../../../.svelte-kit/adapter-node/entries/endpoints/api/qr-config/_server.ts.js"],"sourcesContent":["import { b as private_env } from \"../../../../chunks/shared-server.js\";\nimport { v as validateAuth } from \"../../../../chunks/auth.js\";\nimport { t as toErrorMessage } from \"../../../../chunks/error.js\";\nimport { json } from \"@sveltejs/kit\";\nimport QRCode from \"qrcode\";\nconst GET = async ({ request, url }) => {\n const authError = validateAuth(request);\n if (authError) {\n return authError;\n }\n const apiKey = private_env.API_KEY?.trim();\n if (!apiKey) {\n return json({ error: \"API_KEY not configured on server\" }, { status: 500 });\n }\n const serverUrl = (private_env.ORIGIN?.trim() || url.origin).replace(/\\/+$/, \"\");\n const configPayload = JSON.stringify({\n apiKey,\n registerUrl: `${serverUrl}/api/device-token`,\n serverUrl\n });\n try {\n const dataUrl = await QRCode.toDataURL(configPayload, {\n color: {\n dark: \"#ededed\",\n light: \"#0a0a0a\"\n },\n errorCorrectionLevel: \"M\",\n margin: 2,\n type: \"image/png\",\n width: 280\n });\n return json({ dataUrl, serverUrl });\n } catch (error) {\n console.error(\"[qr-config] QR generation failed:\", toErrorMessage(error));\n return json({ error: \"Failed to generate QR code\" }, { status: 500 });\n }\n};\nexport {\n GET\n};\n"],"names":[],"mappings":";;;;;;;AAKK,MAAC,GAAG,GAAG,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK;AACxC,EAAE,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC;AACzC,EAAE,IAAI,SAAS,EAAE;AACjB,IAAI,OAAO,SAAS;AACpB,EAAE;AACF,EAAE,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,EAAE,IAAI,EAAE;AAC5C,EAAE,IAAI,CAAC,MAAM,EAAE;AACf,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,EAAE,kCAAkC,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AAC/E,EAAE;AACF,EAAE,MAAM,SAAS,GAAG,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;AAClF,EAAE,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC;AACvC,IAAI,MAAM;AACV,IAAI,WAAW,EAAE,CAAC,EAAE,SAAS,CAAC,iBAAiB,CAAC;AAChD,IAAI;AACJ,GAAG,CAAC;AACJ,EAAE,IAAI;AACN,IAAI,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE;AAC1D,MAAM,KAAK,EAAE;AACb,QAAQ,IAAI,EAAE,SAAS;AACvB,QAAQ,KAAK,EAAE;AACf,OAAO;AACP,MAAM,oBAAoB,EAAE,GAAG;AAC/B,MAAM,MAAM,EAAE,CAAC;AACf,MAAM,IAAI,EAAE,WAAW;AACvB,MAAM,KAAK,EAAE;AACb,KAAK,CAAC;AACN,IAAI,OAAO,IAAI,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;AACvC,EAAE,CAAC,CAAC,OAAO,KAAK,EAAE;AAClB,IAAI,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC;AAC7E,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,EAAE,4BAA4B,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AACzE,EAAE;AACF;;;;"}
@@ -0,0 +1,29 @@
1
+ function maskToken(token) {
2
+ if (!token) {
3
+ return "";
4
+ }
5
+ if (token.length < 8) {
6
+ return "••••";
7
+ }
8
+ if (token.length <= 10) {
9
+ return `${token.slice(0, 2)}…${token.slice(-2)}`;
10
+ }
11
+ return `${token.slice(0, 6)}…${token.slice(-4)}`;
12
+ }
13
+ function toDeviceListItem(record) {
14
+ return {
15
+ appEnv: record.appEnv,
16
+ deviceId: record.deviceId,
17
+ failureCount: record.failureCount,
18
+ friendlyName: record.friendlyName,
19
+ id: record.id,
20
+ isActive: record.isActive,
21
+ lastSeenAt: record.lastSeenAt,
22
+ platform: record.platform,
23
+ registeredAt: record.registeredAt,
24
+ tokenMasked: maskToken(record.token)
25
+ };
26
+ }
27
+
28
+ export { maskToken as m, toDeviceListItem as t };
29
+ //# sourceMappingURL=device-format-DTgEz4Yr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-format-DTgEz4Yr.js","sources":["../../../.svelte-kit/adapter-node/chunks/device-format.js"],"sourcesContent":["function maskToken(token) {\n if (!token) {\n return \"\";\n }\n if (token.length < 8) {\n return \"••••\";\n }\n if (token.length <= 10) {\n return `${token.slice(0, 2)}…${token.slice(-2)}`;\n }\n return `${token.slice(0, 6)}…${token.slice(-4)}`;\n}\nfunction toDeviceListItem(record) {\n return {\n appEnv: record.appEnv,\n deviceId: record.deviceId,\n failureCount: record.failureCount,\n friendlyName: record.friendlyName,\n id: record.id,\n isActive: record.isActive,\n lastSeenAt: record.lastSeenAt,\n platform: record.platform,\n registeredAt: record.registeredAt,\n tokenMasked: maskToken(record.token)\n };\n}\nexport {\n maskToken as m,\n toDeviceListItem as t\n};\n"],"names":[],"mappings":"AAAA,SAAS,SAAS,CAAC,KAAK,EAAE;AAC1B,EAAE,IAAI,CAAC,KAAK,EAAE;AACd,IAAI,OAAO,EAAE;AACb,EAAE;AACF,EAAE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;AACxB,IAAI,OAAO,MAAM;AACjB,EAAE;AACF,EAAE,IAAI,KAAK,CAAC,MAAM,IAAI,EAAE,EAAE;AAC1B,IAAI,OAAO,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;AACpD,EAAE;AACF,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;AAClD;AACA,SAAS,gBAAgB,CAAC,MAAM,EAAE;AAClC,EAAE,OAAO;AACT,IAAI,MAAM,EAAE,MAAM,CAAC,MAAM;AACzB,IAAI,QAAQ,EAAE,MAAM,CAAC,QAAQ;AAC7B,IAAI,YAAY,EAAE,MAAM,CAAC,YAAY;AACrC,IAAI,YAAY,EAAE,MAAM,CAAC,YAAY;AACrC,IAAI,EAAE,EAAE,MAAM,CAAC,EAAE;AACjB,IAAI,QAAQ,EAAE,MAAM,CAAC,QAAQ;AAC7B,IAAI,UAAU,EAAE,MAAM,CAAC,UAAU;AACjC,IAAI,QAAQ,EAAE,MAAM,CAAC,QAAQ;AAC7B,IAAI,YAAY,EAAE,MAAM,CAAC,YAAY;AACrC,IAAI,WAAW,EAAE,SAAS,CAAC,MAAM,CAAC,KAAK;AACvC,GAAG;AACH;;;;"}