local-risk-alert-feed 0.1.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 (283) hide show
  1. package/dist/cjs/adapters/index.js +8 -0
  2. package/dist/cjs/adapters/index.js.map +1 -0
  3. package/dist/cjs/adapters/lambda.js +143 -0
  4. package/dist/cjs/adapters/lambda.js.map +1 -0
  5. package/dist/cjs/adapters/vercel.js +119 -0
  6. package/dist/cjs/adapters/vercel.js.map +1 -0
  7. package/dist/cjs/core/alert-aggregator.js +207 -0
  8. package/dist/cjs/core/alert-aggregator.js.map +1 -0
  9. package/dist/cjs/core/alert-feed.js +236 -0
  10. package/dist/cjs/core/alert-feed.js.map +1 -0
  11. package/dist/cjs/core/index.js +22 -0
  12. package/dist/cjs/core/index.js.map +1 -0
  13. package/dist/cjs/core/plugin-registry.js +193 -0
  14. package/dist/cjs/core/plugin-registry.js.map +1 -0
  15. package/dist/cjs/core/plugin-resolver.js +121 -0
  16. package/dist/cjs/core/plugin-resolver.js.map +1 -0
  17. package/dist/cjs/core/time-range.js +67 -0
  18. package/dist/cjs/core/time-range.js.map +1 -0
  19. package/dist/cjs/errors/fetch-error.js +71 -0
  20. package/dist/cjs/errors/fetch-error.js.map +1 -0
  21. package/dist/cjs/errors/index.js +15 -0
  22. package/dist/cjs/errors/index.js.map +1 -0
  23. package/dist/cjs/errors/plugin-error.js +80 -0
  24. package/dist/cjs/errors/plugin-error.js.map +1 -0
  25. package/dist/cjs/errors/validation-error.js +49 -0
  26. package/dist/cjs/errors/validation-error.js.map +1 -0
  27. package/dist/cjs/geo/distance.js +94 -0
  28. package/dist/cjs/geo/distance.js.map +1 -0
  29. package/dist/cjs/geo/index.js +18 -0
  30. package/dist/cjs/geo/index.js.map +1 -0
  31. package/dist/cjs/geo/point-in-radius.js +86 -0
  32. package/dist/cjs/geo/point-in-radius.js.map +1 -0
  33. package/dist/cjs/index.js +90 -0
  34. package/dist/cjs/index.js.map +1 -0
  35. package/dist/cjs/plugins/air-quality/airnow.plugin.js +343 -0
  36. package/dist/cjs/plugins/air-quality/airnow.plugin.js.map +1 -0
  37. package/dist/cjs/plugins/air-quality/index.js +6 -0
  38. package/dist/cjs/plugins/air-quality/index.js.map +1 -0
  39. package/dist/cjs/plugins/base-plugin.js +213 -0
  40. package/dist/cjs/plugins/base-plugin.js.map +1 -0
  41. package/dist/cjs/plugins/events/index.js +6 -0
  42. package/dist/cjs/plugins/events/index.js.map +1 -0
  43. package/dist/cjs/plugins/events/phoenix-events.plugin.js +382 -0
  44. package/dist/cjs/plugins/events/phoenix-events.plugin.js.map +1 -0
  45. package/dist/cjs/plugins/fire-emt/index.js +6 -0
  46. package/dist/cjs/plugins/fire-emt/index.js.map +1 -0
  47. package/dist/cjs/plugins/fire-emt/phoenix-fire.plugin.js +262 -0
  48. package/dist/cjs/plugins/fire-emt/phoenix-fire.plugin.js.map +1 -0
  49. package/dist/cjs/plugins/index.js +28 -0
  50. package/dist/cjs/plugins/index.js.map +1 -0
  51. package/dist/cjs/plugins/police-blotter/index.js +6 -0
  52. package/dist/cjs/plugins/police-blotter/index.js.map +1 -0
  53. package/dist/cjs/plugins/police-blotter/phoenix-police.plugin.js +198 -0
  54. package/dist/cjs/plugins/police-blotter/phoenix-police.plugin.js.map +1 -0
  55. package/dist/cjs/plugins/pulsepoint/index.js +6 -0
  56. package/dist/cjs/plugins/pulsepoint/index.js.map +1 -0
  57. package/dist/cjs/plugins/pulsepoint/pulsepoint.plugin.js +275 -0
  58. package/dist/cjs/plugins/pulsepoint/pulsepoint.plugin.js.map +1 -0
  59. package/dist/cjs/plugins/traffic/arizona-traffic.plugin.js +391 -0
  60. package/dist/cjs/plugins/traffic/arizona-traffic.plugin.js.map +1 -0
  61. package/dist/cjs/plugins/traffic/index.js +6 -0
  62. package/dist/cjs/plugins/traffic/index.js.map +1 -0
  63. package/dist/cjs/plugins/weather/index.js +6 -0
  64. package/dist/cjs/plugins/weather/index.js.map +1 -0
  65. package/dist/cjs/plugins/weather/nws-weather.plugin.js +180 -0
  66. package/dist/cjs/plugins/weather/nws-weather.plugin.js.map +1 -0
  67. package/dist/cjs/schemas/alert.schema.js +93 -0
  68. package/dist/cjs/schemas/alert.schema.js.map +1 -0
  69. package/dist/cjs/schemas/index.js +24 -0
  70. package/dist/cjs/schemas/index.js.map +1 -0
  71. package/dist/cjs/schemas/query.schema.js +76 -0
  72. package/dist/cjs/schemas/query.schema.js.map +1 -0
  73. package/dist/cjs/types/alert.js +35 -0
  74. package/dist/cjs/types/alert.js.map +1 -0
  75. package/dist/cjs/types/config.js +13 -0
  76. package/dist/cjs/types/config.js.map +1 -0
  77. package/dist/cjs/types/geo.js +3 -0
  78. package/dist/cjs/types/geo.js.map +1 -0
  79. package/dist/cjs/types/index.js +16 -0
  80. package/dist/cjs/types/index.js.map +1 -0
  81. package/dist/cjs/types/plugin.js +3 -0
  82. package/dist/cjs/types/plugin.js.map +1 -0
  83. package/dist/cjs/types/query.js +28 -0
  84. package/dist/cjs/types/query.js.map +1 -0
  85. package/dist/cjs/utils/cache.js +188 -0
  86. package/dist/cjs/utils/cache.js.map +1 -0
  87. package/dist/cjs/utils/csv.js +189 -0
  88. package/dist/cjs/utils/csv.js.map +1 -0
  89. package/dist/cjs/utils/date.js +153 -0
  90. package/dist/cjs/utils/date.js.map +1 -0
  91. package/dist/cjs/utils/index.js +28 -0
  92. package/dist/cjs/utils/index.js.map +1 -0
  93. package/dist/cjs/utils/retry.js +109 -0
  94. package/dist/cjs/utils/retry.js.map +1 -0
  95. package/dist/esm/adapters/index.js +3 -0
  96. package/dist/esm/adapters/index.js.map +1 -0
  97. package/dist/esm/adapters/lambda.js +140 -0
  98. package/dist/esm/adapters/lambda.js.map +1 -0
  99. package/dist/esm/adapters/vercel.js +116 -0
  100. package/dist/esm/adapters/vercel.js.map +1 -0
  101. package/dist/esm/core/alert-aggregator.js +203 -0
  102. package/dist/esm/core/alert-aggregator.js.map +1 -0
  103. package/dist/esm/core/alert-feed.js +232 -0
  104. package/dist/esm/core/alert-feed.js.map +1 -0
  105. package/dist/esm/core/index.js +6 -0
  106. package/dist/esm/core/index.js.map +1 -0
  107. package/dist/esm/core/plugin-registry.js +189 -0
  108. package/dist/esm/core/plugin-registry.js.map +1 -0
  109. package/dist/esm/core/plugin-resolver.js +117 -0
  110. package/dist/esm/core/plugin-resolver.js.map +1 -0
  111. package/dist/esm/core/time-range.js +57 -0
  112. package/dist/esm/core/time-range.js.map +1 -0
  113. package/dist/esm/errors/fetch-error.js +67 -0
  114. package/dist/esm/errors/fetch-error.js.map +1 -0
  115. package/dist/esm/errors/index.js +4 -0
  116. package/dist/esm/errors/index.js.map +1 -0
  117. package/dist/esm/errors/plugin-error.js +71 -0
  118. package/dist/esm/errors/plugin-error.js.map +1 -0
  119. package/dist/esm/errors/validation-error.js +45 -0
  120. package/dist/esm/errors/validation-error.js.map +1 -0
  121. package/dist/esm/geo/distance.js +85 -0
  122. package/dist/esm/geo/distance.js.map +1 -0
  123. package/dist/esm/geo/index.js +3 -0
  124. package/dist/esm/geo/index.js.map +1 -0
  125. package/dist/esm/geo/point-in-radius.js +79 -0
  126. package/dist/esm/geo/point-in-radius.js.map +1 -0
  127. package/dist/esm/index.js +30 -0
  128. package/dist/esm/index.js.map +1 -0
  129. package/dist/esm/plugins/air-quality/airnow.plugin.js +339 -0
  130. package/dist/esm/plugins/air-quality/airnow.plugin.js.map +1 -0
  131. package/dist/esm/plugins/air-quality/index.js +2 -0
  132. package/dist/esm/plugins/air-quality/index.js.map +1 -0
  133. package/dist/esm/plugins/base-plugin.js +209 -0
  134. package/dist/esm/plugins/base-plugin.js.map +1 -0
  135. package/dist/esm/plugins/events/index.js +2 -0
  136. package/dist/esm/plugins/events/index.js.map +1 -0
  137. package/dist/esm/plugins/events/phoenix-events.plugin.js +378 -0
  138. package/dist/esm/plugins/events/phoenix-events.plugin.js.map +1 -0
  139. package/dist/esm/plugins/fire-emt/index.js +2 -0
  140. package/dist/esm/plugins/fire-emt/index.js.map +1 -0
  141. package/dist/esm/plugins/fire-emt/phoenix-fire.plugin.js +258 -0
  142. package/dist/esm/plugins/fire-emt/phoenix-fire.plugin.js.map +1 -0
  143. package/dist/esm/plugins/index.js +17 -0
  144. package/dist/esm/plugins/index.js.map +1 -0
  145. package/dist/esm/plugins/police-blotter/index.js +2 -0
  146. package/dist/esm/plugins/police-blotter/index.js.map +1 -0
  147. package/dist/esm/plugins/police-blotter/phoenix-police.plugin.js +194 -0
  148. package/dist/esm/plugins/police-blotter/phoenix-police.plugin.js.map +1 -0
  149. package/dist/esm/plugins/pulsepoint/index.js +2 -0
  150. package/dist/esm/plugins/pulsepoint/index.js.map +1 -0
  151. package/dist/esm/plugins/pulsepoint/pulsepoint.plugin.js +271 -0
  152. package/dist/esm/plugins/pulsepoint/pulsepoint.plugin.js.map +1 -0
  153. package/dist/esm/plugins/traffic/arizona-traffic.plugin.js +387 -0
  154. package/dist/esm/plugins/traffic/arizona-traffic.plugin.js.map +1 -0
  155. package/dist/esm/plugins/traffic/index.js +2 -0
  156. package/dist/esm/plugins/traffic/index.js.map +1 -0
  157. package/dist/esm/plugins/weather/index.js +2 -0
  158. package/dist/esm/plugins/weather/index.js.map +1 -0
  159. package/dist/esm/plugins/weather/nws-weather.plugin.js +176 -0
  160. package/dist/esm/plugins/weather/nws-weather.plugin.js.map +1 -0
  161. package/dist/esm/schemas/alert.schema.js +90 -0
  162. package/dist/esm/schemas/alert.schema.js.map +1 -0
  163. package/dist/esm/schemas/index.js +5 -0
  164. package/dist/esm/schemas/index.js.map +1 -0
  165. package/dist/esm/schemas/query.schema.js +72 -0
  166. package/dist/esm/schemas/query.schema.js.map +1 -0
  167. package/dist/esm/types/alert.js +32 -0
  168. package/dist/esm/types/alert.js.map +1 -0
  169. package/dist/esm/types/config.js +10 -0
  170. package/dist/esm/types/config.js.map +1 -0
  171. package/dist/esm/types/geo.js +2 -0
  172. package/dist/esm/types/geo.js.map +1 -0
  173. package/dist/esm/types/index.js +4 -0
  174. package/dist/esm/types/index.js.map +1 -0
  175. package/dist/esm/types/plugin.js +2 -0
  176. package/dist/esm/types/plugin.js.map +1 -0
  177. package/dist/esm/types/query.js +25 -0
  178. package/dist/esm/types/query.js.map +1 -0
  179. package/dist/esm/utils/cache.js +181 -0
  180. package/dist/esm/utils/cache.js.map +1 -0
  181. package/dist/esm/utils/csv.js +185 -0
  182. package/dist/esm/utils/csv.js.map +1 -0
  183. package/dist/esm/utils/date.js +142 -0
  184. package/dist/esm/utils/date.js.map +1 -0
  185. package/dist/esm/utils/index.js +5 -0
  186. package/dist/esm/utils/index.js.map +1 -0
  187. package/dist/esm/utils/retry.js +102 -0
  188. package/dist/esm/utils/retry.js.map +1 -0
  189. package/dist/types/adapters/index.d.ts +5 -0
  190. package/dist/types/adapters/index.d.ts.map +1 -0
  191. package/dist/types/adapters/lambda.d.ts +37 -0
  192. package/dist/types/adapters/lambda.d.ts.map +1 -0
  193. package/dist/types/adapters/vercel.d.ts +54 -0
  194. package/dist/types/adapters/vercel.d.ts.map +1 -0
  195. package/dist/types/core/alert-aggregator.d.ts +81 -0
  196. package/dist/types/core/alert-aggregator.d.ts.map +1 -0
  197. package/dist/types/core/alert-feed.d.ts +80 -0
  198. package/dist/types/core/alert-feed.d.ts.map +1 -0
  199. package/dist/types/core/index.d.ts +8 -0
  200. package/dist/types/core/index.d.ts.map +1 -0
  201. package/dist/types/core/plugin-registry.d.ts +91 -0
  202. package/dist/types/core/plugin-registry.d.ts.map +1 -0
  203. package/dist/types/core/plugin-resolver.d.ts +78 -0
  204. package/dist/types/core/plugin-resolver.d.ts.map +1 -0
  205. package/dist/types/core/time-range.d.ts +40 -0
  206. package/dist/types/core/time-range.d.ts.map +1 -0
  207. package/dist/types/errors/fetch-error.d.ts +46 -0
  208. package/dist/types/errors/fetch-error.d.ts.map +1 -0
  209. package/dist/types/errors/index.d.ts +5 -0
  210. package/dist/types/errors/index.d.ts.map +1 -0
  211. package/dist/types/errors/plugin-error.d.ts +42 -0
  212. package/dist/types/errors/plugin-error.d.ts.map +1 -0
  213. package/dist/types/errors/validation-error.d.ts +34 -0
  214. package/dist/types/errors/validation-error.d.ts.map +1 -0
  215. package/dist/types/geo/distance.d.ts +50 -0
  216. package/dist/types/geo/distance.d.ts.map +1 -0
  217. package/dist/types/geo/index.d.ts +3 -0
  218. package/dist/types/geo/index.d.ts.map +1 -0
  219. package/dist/types/geo/point-in-radius.d.ts +44 -0
  220. package/dist/types/geo/point-in-radius.d.ts.map +1 -0
  221. package/dist/types/index.d.ts +32 -0
  222. package/dist/types/index.d.ts.map +1 -0
  223. package/dist/types/plugins/air-quality/airnow.plugin.d.ts +84 -0
  224. package/dist/types/plugins/air-quality/airnow.plugin.d.ts.map +1 -0
  225. package/dist/types/plugins/air-quality/index.d.ts +3 -0
  226. package/dist/types/plugins/air-quality/index.d.ts.map +1 -0
  227. package/dist/types/plugins/base-plugin.d.ts +99 -0
  228. package/dist/types/plugins/base-plugin.d.ts.map +1 -0
  229. package/dist/types/plugins/events/index.d.ts +3 -0
  230. package/dist/types/plugins/events/index.d.ts.map +1 -0
  231. package/dist/types/plugins/events/phoenix-events.plugin.d.ts +71 -0
  232. package/dist/types/plugins/events/phoenix-events.plugin.d.ts.map +1 -0
  233. package/dist/types/plugins/fire-emt/index.d.ts +3 -0
  234. package/dist/types/plugins/fire-emt/index.d.ts.map +1 -0
  235. package/dist/types/plugins/fire-emt/phoenix-fire.plugin.d.ts +47 -0
  236. package/dist/types/plugins/fire-emt/phoenix-fire.plugin.d.ts.map +1 -0
  237. package/dist/types/plugins/index.d.ts +17 -0
  238. package/dist/types/plugins/index.d.ts.map +1 -0
  239. package/dist/types/plugins/police-blotter/index.d.ts +3 -0
  240. package/dist/types/plugins/police-blotter/index.d.ts.map +1 -0
  241. package/dist/types/plugins/police-blotter/phoenix-police.plugin.d.ts +49 -0
  242. package/dist/types/plugins/police-blotter/phoenix-police.plugin.d.ts.map +1 -0
  243. package/dist/types/plugins/pulsepoint/index.d.ts +3 -0
  244. package/dist/types/plugins/pulsepoint/index.d.ts.map +1 -0
  245. package/dist/types/plugins/pulsepoint/pulsepoint.plugin.d.ts +61 -0
  246. package/dist/types/plugins/pulsepoint/pulsepoint.plugin.d.ts.map +1 -0
  247. package/dist/types/plugins/traffic/arizona-traffic.plugin.d.ts +83 -0
  248. package/dist/types/plugins/traffic/arizona-traffic.plugin.d.ts.map +1 -0
  249. package/dist/types/plugins/traffic/index.d.ts +3 -0
  250. package/dist/types/plugins/traffic/index.d.ts.map +1 -0
  251. package/dist/types/plugins/weather/index.d.ts +3 -0
  252. package/dist/types/plugins/weather/index.d.ts.map +1 -0
  253. package/dist/types/plugins/weather/nws-weather.plugin.d.ts +50 -0
  254. package/dist/types/plugins/weather/nws-weather.plugin.d.ts.map +1 -0
  255. package/dist/types/schemas/alert.schema.d.ts +266 -0
  256. package/dist/types/schemas/alert.schema.d.ts.map +1 -0
  257. package/dist/types/schemas/index.d.ts +5 -0
  258. package/dist/types/schemas/index.d.ts.map +1 -0
  259. package/dist/types/schemas/query.schema.d.ts +150 -0
  260. package/dist/types/schemas/query.schema.d.ts.map +1 -0
  261. package/dist/types/types/alert.d.ts +96 -0
  262. package/dist/types/types/alert.d.ts.map +1 -0
  263. package/dist/types/types/config.d.ts +63 -0
  264. package/dist/types/types/config.d.ts.map +1 -0
  265. package/dist/types/types/geo.d.ts +33 -0
  266. package/dist/types/types/geo.d.ts.map +1 -0
  267. package/dist/types/types/index.d.ts +9 -0
  268. package/dist/types/types/index.d.ts.map +1 -0
  269. package/dist/types/types/plugin.d.ts +125 -0
  270. package/dist/types/types/plugin.d.ts.map +1 -0
  271. package/dist/types/types/query.d.ts +86 -0
  272. package/dist/types/types/query.d.ts.map +1 -0
  273. package/dist/types/utils/cache.d.ts +112 -0
  274. package/dist/types/utils/cache.d.ts.map +1 -0
  275. package/dist/types/utils/csv.d.ts +38 -0
  276. package/dist/types/utils/csv.d.ts.map +1 -0
  277. package/dist/types/utils/date.d.ts +47 -0
  278. package/dist/types/utils/date.d.ts.map +1 -0
  279. package/dist/types/utils/index.d.ts +7 -0
  280. package/dist/types/utils/index.d.ts.map +1 -0
  281. package/dist/types/utils/retry.d.ts +51 -0
  282. package/dist/types/utils/retry.d.ts.map +1 -0
  283. package/package.json +115 -0
@@ -0,0 +1,116 @@
1
+ import { AlertFeed } from '../core';
2
+ import { AlertQueryRequestSchema, transformRequestToQuery } from '../schemas';
3
+ import { ValidationError } from '../errors';
4
+ /**
5
+ * Create Next.js App Router handlers for the AlertFeed.
6
+ *
7
+ * Returns GET and POST handlers that can be exported from a route file.
8
+ *
9
+ * @param options - Handler configuration options
10
+ * @returns Object with GET and POST handlers
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * // app/api/alerts/route.ts
15
+ * import { createVercelHandler } from 'local-risk-alert-feed/adapters/vercel';
16
+ * import { PhoenixPolicePlugin } from 'local-risk-alert-feed/plugins/police-blotter';
17
+ *
18
+ * const { GET, POST } = createVercelHandler({
19
+ * plugins: [{ plugin: new PhoenixPolicePlugin() }]
20
+ * });
21
+ *
22
+ * export { GET, POST };
23
+ * ```
24
+ */
25
+ export function createVercelHandler(options) {
26
+ const feed = new AlertFeed(options);
27
+ const corsOrigin = options.corsOrigin ?? '*';
28
+ // Initialize plugins
29
+ if (options.plugins) {
30
+ feed.registerPlugins(options.plugins).catch(console.error);
31
+ }
32
+ const handleRequest = async (request) => {
33
+ try {
34
+ // Parse request
35
+ const requestData = await parseRequest(request);
36
+ // Validate request
37
+ const parseResult = AlertQueryRequestSchema.safeParse(requestData);
38
+ if (!parseResult.success) {
39
+ return createErrorResponse(400, 'Validation Error', ValidationError.fromZodError(parseResult.error).toJSON(), corsOrigin);
40
+ }
41
+ // Transform to query
42
+ const query = transformRequestToQuery(parseResult.data);
43
+ // Execute query
44
+ const response = await feed.query(query);
45
+ return createSuccessResponse(response, corsOrigin);
46
+ }
47
+ catch (error) {
48
+ console.error('AlertFeed error:', error);
49
+ if (error instanceof ValidationError) {
50
+ return createErrorResponse(400, 'Validation Error', error.toJSON(), corsOrigin);
51
+ }
52
+ return createErrorResponse(500, 'Internal Server Error', {
53
+ message: error instanceof Error ? error.message : 'An unexpected error occurred',
54
+ }, corsOrigin);
55
+ }
56
+ };
57
+ return {
58
+ GET: handleRequest,
59
+ POST: handleRequest,
60
+ };
61
+ }
62
+ /**
63
+ * Parse request data from Next.js request.
64
+ */
65
+ async function parseRequest(request) {
66
+ if (request.method === 'POST') {
67
+ try {
68
+ return (await request.json());
69
+ }
70
+ catch {
71
+ throw new ValidationError('Invalid JSON body', [
72
+ { path: 'body', message: 'Request body must be valid JSON', code: 'invalid_type' },
73
+ ]);
74
+ }
75
+ }
76
+ // Parse from query parameters
77
+ const params = request.nextUrl.searchParams;
78
+ return {
79
+ latitude: params.has('latitude') ? parseFloat(params.get('latitude')) : undefined,
80
+ longitude: params.has('longitude') ? parseFloat(params.get('longitude')) : undefined,
81
+ radiusMeters: params.has('radiusMeters') ? parseFloat(params.get('radiusMeters')) : undefined,
82
+ limit: params.has('limit') ? parseInt(params.get('limit'), 10) : undefined,
83
+ minRiskLevel: params.get('minRiskLevel') ?? undefined,
84
+ timeRange: params.get('timeRange') ?? undefined,
85
+ categories: params.getAll('categories').length > 0 ? params.getAll('categories') : undefined,
86
+ temporalTypes: params.getAll('temporalTypes').length > 0 ? params.getAll('temporalTypes') : undefined,
87
+ includePluginResults: params.get('includePluginResults') === 'true',
88
+ };
89
+ }
90
+ /**
91
+ * Create a success response.
92
+ */
93
+ function createSuccessResponse(data, corsOrigin) {
94
+ const origin = Array.isArray(corsOrigin) ? corsOrigin[0] : corsOrigin;
95
+ return new Response(JSON.stringify(data), {
96
+ status: 200,
97
+ headers: {
98
+ 'Content-Type': 'application/json',
99
+ 'Access-Control-Allow-Origin': origin,
100
+ },
101
+ });
102
+ }
103
+ /**
104
+ * Create an error response.
105
+ */
106
+ function createErrorResponse(statusCode, error, details, corsOrigin) {
107
+ const origin = Array.isArray(corsOrigin) ? corsOrigin[0] : corsOrigin;
108
+ return new Response(JSON.stringify({ error, ...details }), {
109
+ status: statusCode,
110
+ headers: {
111
+ 'Content-Type': 'application/json',
112
+ 'Access-Control-Allow-Origin': origin,
113
+ },
114
+ });
115
+ }
116
+ //# sourceMappingURL=vercel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vercel.js","sourceRoot":"","sources":["../../../src/adapters/vercel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,203 @@
1
+ import { RISK_LEVEL_VALUES } from '../types';
2
+ import { haversineDistance } from '../geo';
3
+ /**
4
+ * Aggregates, filters, deduplicates, and sorts alerts from multiple sources.
5
+ */
6
+ export class AlertAggregator {
7
+ /**
8
+ * Aggregate alerts from multiple sources.
9
+ *
10
+ * Combines alerts, removes duplicates, filters by criteria, and sorts.
11
+ *
12
+ * @param alertSets - Arrays of alerts from different plugins
13
+ * @param options - Aggregation options
14
+ * @returns Aggregated and filtered alerts
15
+ */
16
+ aggregate(alertSets, options = {}) {
17
+ // Flatten all alerts
18
+ let alerts = alertSets.flat();
19
+ // Deduplicate
20
+ alerts = this.deduplicate(alerts);
21
+ // Filter by risk level
22
+ if (options.minRiskLevel) {
23
+ alerts = this.filterByRiskLevel(alerts, options.minRiskLevel);
24
+ }
25
+ // Filter by time range
26
+ if (options.timeRange) {
27
+ alerts = this.filterByTimeRange(alerts, options.timeRange);
28
+ }
29
+ // Filter by location radius
30
+ if (options.location && options.radiusMeters) {
31
+ alerts = this.filterByRadius(alerts, options.location, options.radiusMeters);
32
+ }
33
+ // Sort by priority (primary) and time (secondary)
34
+ alerts = this.sort(alerts, ['priority-asc', 'time-desc']);
35
+ // Apply limit
36
+ if (options.limit && alerts.length > options.limit) {
37
+ alerts = alerts.slice(0, options.limit);
38
+ }
39
+ return alerts;
40
+ }
41
+ /**
42
+ * Remove duplicate alerts based on ID and source.
43
+ *
44
+ * If two alerts have the same external ID from the same source,
45
+ * keep the one with the most recent issued timestamp.
46
+ */
47
+ deduplicate(alerts) {
48
+ const seen = new Map();
49
+ for (const alert of alerts) {
50
+ // Primary dedup key: alert ID
51
+ const primaryKey = alert.id;
52
+ // Secondary dedup key: source external ID (if available)
53
+ const secondaryKey = alert.source.externalId
54
+ ? `${alert.source.pluginId}:${alert.source.externalId}`
55
+ : null;
56
+ // Check primary key
57
+ const existingPrimary = seen.get(primaryKey);
58
+ if (existingPrimary) {
59
+ // Keep the more recent one
60
+ if (new Date(alert.timestamps.issued) > new Date(existingPrimary.timestamps.issued)) {
61
+ seen.set(primaryKey, alert);
62
+ }
63
+ continue;
64
+ }
65
+ // Check secondary key
66
+ if (secondaryKey) {
67
+ const existingSecondary = seen.get(secondaryKey);
68
+ if (existingSecondary) {
69
+ if (new Date(alert.timestamps.issued) > new Date(existingSecondary.timestamps.issued)) {
70
+ seen.set(secondaryKey, alert);
71
+ }
72
+ continue;
73
+ }
74
+ seen.set(secondaryKey, alert);
75
+ }
76
+ seen.set(primaryKey, alert);
77
+ }
78
+ return Array.from(seen.values());
79
+ }
80
+ /**
81
+ * Filter alerts by minimum risk level.
82
+ */
83
+ filterByRiskLevel(alerts, minLevel) {
84
+ const minValue = RISK_LEVEL_VALUES[minLevel];
85
+ return alerts.filter((alert) => RISK_LEVEL_VALUES[alert.riskLevel] >= minValue);
86
+ }
87
+ /**
88
+ * Filter alerts by time range.
89
+ *
90
+ * Includes alerts where:
91
+ * - The issued timestamp falls within the range, OR
92
+ * - The event start/end times overlap with the range
93
+ */
94
+ filterByTimeRange(alerts, range) {
95
+ const rangeStart = new Date(range.start).getTime();
96
+ const rangeEnd = new Date(range.end).getTime();
97
+ return alerts.filter((alert) => {
98
+ // Check if issued time is in range
99
+ const issuedTime = new Date(alert.timestamps.issued).getTime();
100
+ if (issuedTime >= rangeStart && issuedTime <= rangeEnd) {
101
+ return true;
102
+ }
103
+ // Check if event times overlap
104
+ const eventStart = alert.timestamps.eventStart
105
+ ? new Date(alert.timestamps.eventStart).getTime()
106
+ : null;
107
+ const eventEnd = alert.timestamps.eventEnd
108
+ ? new Date(alert.timestamps.eventEnd).getTime()
109
+ : null;
110
+ if (eventStart !== null && eventEnd !== null) {
111
+ // Event has both start and end - check for overlap
112
+ return eventStart <= rangeEnd && eventEnd >= rangeStart;
113
+ }
114
+ if (eventStart !== null) {
115
+ // Only start time - check if it's in range
116
+ return eventStart >= rangeStart && eventStart <= rangeEnd;
117
+ }
118
+ return false;
119
+ });
120
+ }
121
+ /**
122
+ * Filter alerts by distance from a center point.
123
+ */
124
+ filterByRadius(alerts, center, radiusMeters) {
125
+ return alerts.filter((alert) => {
126
+ const distance = haversineDistance(center, alert.location.point);
127
+ return distance <= radiusMeters;
128
+ });
129
+ }
130
+ /**
131
+ * Sort alerts by one or more criteria.
132
+ *
133
+ * Later criteria are used as tiebreakers.
134
+ */
135
+ sort(alerts, orders) {
136
+ return [...alerts].sort((a, b) => {
137
+ for (const order of orders) {
138
+ const comparison = this.compare(a, b, order);
139
+ if (comparison !== 0)
140
+ return comparison;
141
+ }
142
+ return 0;
143
+ });
144
+ }
145
+ /**
146
+ * Compare two alerts based on a sort order.
147
+ */
148
+ compare(a, b, order) {
149
+ switch (order) {
150
+ case 'priority-asc':
151
+ return a.priority - b.priority;
152
+ case 'priority-desc':
153
+ return b.priority - a.priority;
154
+ case 'risk-asc':
155
+ return RISK_LEVEL_VALUES[a.riskLevel] - RISK_LEVEL_VALUES[b.riskLevel];
156
+ case 'risk-desc':
157
+ return RISK_LEVEL_VALUES[b.riskLevel] - RISK_LEVEL_VALUES[a.riskLevel];
158
+ case 'time-asc':
159
+ return new Date(a.timestamps.issued).getTime() - new Date(b.timestamps.issued).getTime();
160
+ case 'time-desc':
161
+ return new Date(b.timestamps.issued).getTime() - new Date(a.timestamps.issued).getTime();
162
+ case 'distance-asc':
163
+ case 'distance-desc':
164
+ // Distance sorting requires a reference point, not supported in basic compare
165
+ return 0;
166
+ }
167
+ }
168
+ /**
169
+ * Sort alerts by distance from a center point.
170
+ */
171
+ sortByDistance(alerts, center, ascending = true) {
172
+ return [...alerts].sort((a, b) => {
173
+ const distA = haversineDistance(center, a.location.point);
174
+ const distB = haversineDistance(center, b.location.point);
175
+ return ascending ? distA - distB : distB - distA;
176
+ });
177
+ }
178
+ /**
179
+ * Group alerts by category.
180
+ */
181
+ groupByCategory(alerts) {
182
+ const groups = new Map();
183
+ for (const alert of alerts) {
184
+ const existing = groups.get(alert.category) ?? [];
185
+ existing.push(alert);
186
+ groups.set(alert.category, existing);
187
+ }
188
+ return groups;
189
+ }
190
+ /**
191
+ * Group alerts by source plugin.
192
+ */
193
+ groupBySource(alerts) {
194
+ const groups = new Map();
195
+ for (const alert of alerts) {
196
+ const existing = groups.get(alert.source.pluginId) ?? [];
197
+ existing.push(alert);
198
+ groups.set(alert.source.pluginId, existing);
199
+ }
200
+ return groups;
201
+ }
202
+ }
203
+ //# sourceMappingURL=alert-aggregator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alert-aggregator.js","sourceRoot":"","sources":["../../../src/core/alert-aggregator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,232 @@
1
+ import { DEFAULT_QUERY_RADIUS_METERS, DEFAULT_QUERY_LIMIT } from '../types';
2
+ import { PluginRegistry } from './plugin-registry';
3
+ import { PluginResolver } from './plugin-resolver';
4
+ import { AlertAggregator } from './alert-aggregator';
5
+ import { normalizeTimeRange } from './time-range';
6
+ import { PluginFetchError, PluginTimeoutError } from '../errors';
7
+ import { withTimeout } from '../utils';
8
+ /**
9
+ * Main AlertFeed class that coordinates plugin fetching and alert aggregation.
10
+ */
11
+ export class AlertFeed {
12
+ registry;
13
+ resolver;
14
+ aggregator;
15
+ config;
16
+ constructor(config) {
17
+ this.registry = new PluginRegistry();
18
+ this.resolver = new PluginResolver();
19
+ this.aggregator = new AlertAggregator();
20
+ this.config = {
21
+ defaultCacheTtlMs: config?.defaultCacheTtlMs ?? 5 * 60 * 1000,
22
+ pluginTimeoutMs: config?.pluginTimeoutMs ?? 30 * 1000,
23
+ continueOnPluginError: config?.continueOnPluginError ?? true,
24
+ maxConcurrentFetches: config?.maxConcurrentFetches ?? 5,
25
+ };
26
+ // Register initial plugins if provided
27
+ if (config?.plugins) {
28
+ // Don't await here - call registerPlugins separately
29
+ this.registerPluginsSync(config.plugins);
30
+ }
31
+ }
32
+ /**
33
+ * Register plugins synchronously (for constructor use).
34
+ * Initialization happens lazily on first query.
35
+ */
36
+ registerPluginsSync(registrations) {
37
+ for (const reg of registrations) {
38
+ // Queue registration without awaiting
39
+ this.registry.register(reg).catch(() => {
40
+ // Errors will be caught on first query
41
+ });
42
+ }
43
+ }
44
+ /**
45
+ * Register plugins with the feed.
46
+ *
47
+ * @param registrations - Array of plugin registrations
48
+ */
49
+ async registerPlugins(registrations) {
50
+ await this.registry.registerAll(registrations);
51
+ }
52
+ /**
53
+ * Register a single plugin.
54
+ *
55
+ * @param registration - Plugin registration
56
+ */
57
+ async registerPlugin(registration) {
58
+ await this.registry.register(registration);
59
+ }
60
+ /**
61
+ * Unregister a plugin by ID.
62
+ *
63
+ * @param pluginId - The plugin ID to unregister
64
+ */
65
+ async unregisterPlugin(pluginId) {
66
+ await this.registry.unregister(pluginId);
67
+ }
68
+ /**
69
+ * Query for alerts based on location and filters.
70
+ *
71
+ * @param query - Query parameters
72
+ * @returns Query response with alerts and metadata
73
+ */
74
+ async query(query) {
75
+ // Normalize query parameters
76
+ const radiusMeters = query.radiusMeters ?? DEFAULT_QUERY_RADIUS_METERS;
77
+ const limit = query.limit ?? DEFAULT_QUERY_LIMIT;
78
+ const timeRange = normalizeTimeRange(query.timeRange);
79
+ // Get all enabled plugins
80
+ const allPlugins = this.registry.getAll(true);
81
+ // Resolve which plugins to query based on location and filters
82
+ const applicablePlugins = this.resolver.resolve(allPlugins, {
83
+ location: query.location,
84
+ categories: query.categories,
85
+ temporalTypes: query.temporalTypes,
86
+ });
87
+ // Fetch from all applicable plugins
88
+ const { alertSets, pluginResults } = await this.fetchFromPlugins(applicablePlugins, {
89
+ location: query.location,
90
+ radiusMeters,
91
+ timeRange,
92
+ limit,
93
+ categories: query.categories,
94
+ temporalTypes: query.temporalTypes,
95
+ }, query.includePluginResults ?? false);
96
+ // Aggregate alerts
97
+ const aggregatedAlerts = this.aggregator.aggregate(alertSets, {
98
+ minRiskLevel: query.minRiskLevel,
99
+ timeRange,
100
+ location: query.location,
101
+ radiusMeters,
102
+ limit,
103
+ });
104
+ const truncated = aggregatedAlerts.length < this.getTotalAlertCount(alertSets);
105
+ // Build response
106
+ const response = {
107
+ alerts: aggregatedAlerts,
108
+ meta: {
109
+ totalCount: aggregatedAlerts.length,
110
+ queriedAt: new Date().toISOString(),
111
+ timeRange,
112
+ location: query.location,
113
+ radiusMeters,
114
+ truncated,
115
+ },
116
+ };
117
+ if (query.includePluginResults) {
118
+ response.pluginResults = pluginResults;
119
+ }
120
+ return response;
121
+ }
122
+ /**
123
+ * Fetch alerts from multiple plugins with concurrency control.
124
+ */
125
+ async fetchFromPlugins(plugins, options, includeResults) {
126
+ const alertSets = [];
127
+ const pluginResults = [];
128
+ // Process plugins with concurrency limit
129
+ const chunks = this.chunkArray(plugins, this.config.maxConcurrentFetches);
130
+ for (const chunk of chunks) {
131
+ const chunkResults = await Promise.all(chunk.map((plugin) => this.fetchFromPlugin(plugin, options)));
132
+ for (const result of chunkResults) {
133
+ alertSets.push(result.alerts);
134
+ if (includeResults) {
135
+ pluginResults.push(result.info);
136
+ }
137
+ }
138
+ }
139
+ return { alertSets, pluginResults };
140
+ }
141
+ /**
142
+ * Fetch alerts from a single plugin with timeout handling.
143
+ */
144
+ async fetchFromPlugin(plugin, options) {
145
+ const startTime = Date.now();
146
+ const pluginId = plugin.metadata.id;
147
+ const pluginName = plugin.metadata.name;
148
+ try {
149
+ const result = await withTimeout(() => plugin.fetchAlerts(options), this.config.pluginTimeoutMs, `Plugin "${pluginId}" timed out`);
150
+ return {
151
+ alerts: result.alerts,
152
+ info: {
153
+ pluginId,
154
+ pluginName,
155
+ success: true,
156
+ alertCount: result.alerts.length,
157
+ durationMs: Date.now() - startTime,
158
+ fromCache: result.fromCache,
159
+ warnings: result.warnings,
160
+ },
161
+ };
162
+ }
163
+ catch (error) {
164
+ const durationMs = Date.now() - startTime;
165
+ const errorMessage = error instanceof Error ? error.message : String(error);
166
+ const info = {
167
+ pluginId,
168
+ pluginName,
169
+ success: false,
170
+ alertCount: 0,
171
+ durationMs,
172
+ error: errorMessage,
173
+ };
174
+ if (!this.config.continueOnPluginError) {
175
+ if (error instanceof PluginTimeoutError) {
176
+ throw error;
177
+ }
178
+ throw new PluginFetchError(pluginId, errorMessage, error instanceof Error ? error : undefined);
179
+ }
180
+ return { alerts: [], info };
181
+ }
182
+ }
183
+ /**
184
+ * Get total count of alerts across all sets.
185
+ */
186
+ getTotalAlertCount(alertSets) {
187
+ return alertSets.reduce((sum, set) => sum + set.length, 0);
188
+ }
189
+ /**
190
+ * Split an array into chunks.
191
+ */
192
+ chunkArray(array, size) {
193
+ const chunks = [];
194
+ for (let i = 0; i < array.length; i += size) {
195
+ chunks.push(array.slice(i, i + size));
196
+ }
197
+ return chunks;
198
+ }
199
+ /**
200
+ * Get registered plugin metadata.
201
+ *
202
+ * @param enabledOnly - Only return enabled plugins (default: true)
203
+ */
204
+ getPluginMetadata(enabledOnly = true) {
205
+ return this.registry.getMetadata(enabledOnly);
206
+ }
207
+ /**
208
+ * Check if a plugin is registered.
209
+ */
210
+ hasPlugin(pluginId) {
211
+ return this.registry.has(pluginId);
212
+ }
213
+ /**
214
+ * Enable a plugin.
215
+ */
216
+ async enablePlugin(pluginId) {
217
+ await this.registry.enable(pluginId);
218
+ }
219
+ /**
220
+ * Disable a plugin.
221
+ */
222
+ disablePlugin(pluginId) {
223
+ this.registry.disable(pluginId);
224
+ }
225
+ /**
226
+ * Dispose of the feed and all plugins.
227
+ */
228
+ async dispose() {
229
+ await this.registry.dispose();
230
+ }
231
+ }
232
+ //# sourceMappingURL=alert-feed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alert-feed.js","sourceRoot":"","sources":["../../../src/core/alert-feed.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export { AlertFeed } from './alert-feed';
2
+ export { PluginRegistry } from './plugin-registry';
3
+ export { PluginResolver } from './plugin-resolver';
4
+ export { AlertAggregator } from './alert-aggregator';
5
+ export { resolveTimeRange, resolveTimeRangePreset, getDefaultTimeRange, getDefaultTimeRangePreset, normalizeTimeRange, getTimeRangeDuration, isTimeRangeInPast, isTimeRangeInFuture, isTimeRangeCurrent, } from './time-range';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EACzB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,cAAc,CAAC"}