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.
- package/dist/cjs/adapters/index.js +8 -0
- package/dist/cjs/adapters/index.js.map +1 -0
- package/dist/cjs/adapters/lambda.js +143 -0
- package/dist/cjs/adapters/lambda.js.map +1 -0
- package/dist/cjs/adapters/vercel.js +119 -0
- package/dist/cjs/adapters/vercel.js.map +1 -0
- package/dist/cjs/core/alert-aggregator.js +207 -0
- package/dist/cjs/core/alert-aggregator.js.map +1 -0
- package/dist/cjs/core/alert-feed.js +236 -0
- package/dist/cjs/core/alert-feed.js.map +1 -0
- package/dist/cjs/core/index.js +22 -0
- package/dist/cjs/core/index.js.map +1 -0
- package/dist/cjs/core/plugin-registry.js +193 -0
- package/dist/cjs/core/plugin-registry.js.map +1 -0
- package/dist/cjs/core/plugin-resolver.js +121 -0
- package/dist/cjs/core/plugin-resolver.js.map +1 -0
- package/dist/cjs/core/time-range.js +67 -0
- package/dist/cjs/core/time-range.js.map +1 -0
- package/dist/cjs/errors/fetch-error.js +71 -0
- package/dist/cjs/errors/fetch-error.js.map +1 -0
- package/dist/cjs/errors/index.js +15 -0
- package/dist/cjs/errors/index.js.map +1 -0
- package/dist/cjs/errors/plugin-error.js +80 -0
- package/dist/cjs/errors/plugin-error.js.map +1 -0
- package/dist/cjs/errors/validation-error.js +49 -0
- package/dist/cjs/errors/validation-error.js.map +1 -0
- package/dist/cjs/geo/distance.js +94 -0
- package/dist/cjs/geo/distance.js.map +1 -0
- package/dist/cjs/geo/index.js +18 -0
- package/dist/cjs/geo/index.js.map +1 -0
- package/dist/cjs/geo/point-in-radius.js +86 -0
- package/dist/cjs/geo/point-in-radius.js.map +1 -0
- package/dist/cjs/index.js +90 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/plugins/air-quality/airnow.plugin.js +343 -0
- package/dist/cjs/plugins/air-quality/airnow.plugin.js.map +1 -0
- package/dist/cjs/plugins/air-quality/index.js +6 -0
- package/dist/cjs/plugins/air-quality/index.js.map +1 -0
- package/dist/cjs/plugins/base-plugin.js +213 -0
- package/dist/cjs/plugins/base-plugin.js.map +1 -0
- package/dist/cjs/plugins/events/index.js +6 -0
- package/dist/cjs/plugins/events/index.js.map +1 -0
- package/dist/cjs/plugins/events/phoenix-events.plugin.js +382 -0
- package/dist/cjs/plugins/events/phoenix-events.plugin.js.map +1 -0
- package/dist/cjs/plugins/fire-emt/index.js +6 -0
- package/dist/cjs/plugins/fire-emt/index.js.map +1 -0
- package/dist/cjs/plugins/fire-emt/phoenix-fire.plugin.js +262 -0
- package/dist/cjs/plugins/fire-emt/phoenix-fire.plugin.js.map +1 -0
- package/dist/cjs/plugins/index.js +28 -0
- package/dist/cjs/plugins/index.js.map +1 -0
- package/dist/cjs/plugins/police-blotter/index.js +6 -0
- package/dist/cjs/plugins/police-blotter/index.js.map +1 -0
- package/dist/cjs/plugins/police-blotter/phoenix-police.plugin.js +198 -0
- package/dist/cjs/plugins/police-blotter/phoenix-police.plugin.js.map +1 -0
- package/dist/cjs/plugins/pulsepoint/index.js +6 -0
- package/dist/cjs/plugins/pulsepoint/index.js.map +1 -0
- package/dist/cjs/plugins/pulsepoint/pulsepoint.plugin.js +275 -0
- package/dist/cjs/plugins/pulsepoint/pulsepoint.plugin.js.map +1 -0
- package/dist/cjs/plugins/traffic/arizona-traffic.plugin.js +391 -0
- package/dist/cjs/plugins/traffic/arizona-traffic.plugin.js.map +1 -0
- package/dist/cjs/plugins/traffic/index.js +6 -0
- package/dist/cjs/plugins/traffic/index.js.map +1 -0
- package/dist/cjs/plugins/weather/index.js +6 -0
- package/dist/cjs/plugins/weather/index.js.map +1 -0
- package/dist/cjs/plugins/weather/nws-weather.plugin.js +180 -0
- package/dist/cjs/plugins/weather/nws-weather.plugin.js.map +1 -0
- package/dist/cjs/schemas/alert.schema.js +93 -0
- package/dist/cjs/schemas/alert.schema.js.map +1 -0
- package/dist/cjs/schemas/index.js +24 -0
- package/dist/cjs/schemas/index.js.map +1 -0
- package/dist/cjs/schemas/query.schema.js +76 -0
- package/dist/cjs/schemas/query.schema.js.map +1 -0
- package/dist/cjs/types/alert.js +35 -0
- package/dist/cjs/types/alert.js.map +1 -0
- package/dist/cjs/types/config.js +13 -0
- package/dist/cjs/types/config.js.map +1 -0
- package/dist/cjs/types/geo.js +3 -0
- package/dist/cjs/types/geo.js.map +1 -0
- package/dist/cjs/types/index.js +16 -0
- package/dist/cjs/types/index.js.map +1 -0
- package/dist/cjs/types/plugin.js +3 -0
- package/dist/cjs/types/plugin.js.map +1 -0
- package/dist/cjs/types/query.js +28 -0
- package/dist/cjs/types/query.js.map +1 -0
- package/dist/cjs/utils/cache.js +188 -0
- package/dist/cjs/utils/cache.js.map +1 -0
- package/dist/cjs/utils/csv.js +189 -0
- package/dist/cjs/utils/csv.js.map +1 -0
- package/dist/cjs/utils/date.js +153 -0
- package/dist/cjs/utils/date.js.map +1 -0
- package/dist/cjs/utils/index.js +28 -0
- package/dist/cjs/utils/index.js.map +1 -0
- package/dist/cjs/utils/retry.js +109 -0
- package/dist/cjs/utils/retry.js.map +1 -0
- package/dist/esm/adapters/index.js +3 -0
- package/dist/esm/adapters/index.js.map +1 -0
- package/dist/esm/adapters/lambda.js +140 -0
- package/dist/esm/adapters/lambda.js.map +1 -0
- package/dist/esm/adapters/vercel.js +116 -0
- package/dist/esm/adapters/vercel.js.map +1 -0
- package/dist/esm/core/alert-aggregator.js +203 -0
- package/dist/esm/core/alert-aggregator.js.map +1 -0
- package/dist/esm/core/alert-feed.js +232 -0
- package/dist/esm/core/alert-feed.js.map +1 -0
- package/dist/esm/core/index.js +6 -0
- package/dist/esm/core/index.js.map +1 -0
- package/dist/esm/core/plugin-registry.js +189 -0
- package/dist/esm/core/plugin-registry.js.map +1 -0
- package/dist/esm/core/plugin-resolver.js +117 -0
- package/dist/esm/core/plugin-resolver.js.map +1 -0
- package/dist/esm/core/time-range.js +57 -0
- package/dist/esm/core/time-range.js.map +1 -0
- package/dist/esm/errors/fetch-error.js +67 -0
- package/dist/esm/errors/fetch-error.js.map +1 -0
- package/dist/esm/errors/index.js +4 -0
- package/dist/esm/errors/index.js.map +1 -0
- package/dist/esm/errors/plugin-error.js +71 -0
- package/dist/esm/errors/plugin-error.js.map +1 -0
- package/dist/esm/errors/validation-error.js +45 -0
- package/dist/esm/errors/validation-error.js.map +1 -0
- package/dist/esm/geo/distance.js +85 -0
- package/dist/esm/geo/distance.js.map +1 -0
- package/dist/esm/geo/index.js +3 -0
- package/dist/esm/geo/index.js.map +1 -0
- package/dist/esm/geo/point-in-radius.js +79 -0
- package/dist/esm/geo/point-in-radius.js.map +1 -0
- package/dist/esm/index.js +30 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/plugins/air-quality/airnow.plugin.js +339 -0
- package/dist/esm/plugins/air-quality/airnow.plugin.js.map +1 -0
- package/dist/esm/plugins/air-quality/index.js +2 -0
- package/dist/esm/plugins/air-quality/index.js.map +1 -0
- package/dist/esm/plugins/base-plugin.js +209 -0
- package/dist/esm/plugins/base-plugin.js.map +1 -0
- package/dist/esm/plugins/events/index.js +2 -0
- package/dist/esm/plugins/events/index.js.map +1 -0
- package/dist/esm/plugins/events/phoenix-events.plugin.js +378 -0
- package/dist/esm/plugins/events/phoenix-events.plugin.js.map +1 -0
- package/dist/esm/plugins/fire-emt/index.js +2 -0
- package/dist/esm/plugins/fire-emt/index.js.map +1 -0
- package/dist/esm/plugins/fire-emt/phoenix-fire.plugin.js +258 -0
- package/dist/esm/plugins/fire-emt/phoenix-fire.plugin.js.map +1 -0
- package/dist/esm/plugins/index.js +17 -0
- package/dist/esm/plugins/index.js.map +1 -0
- package/dist/esm/plugins/police-blotter/index.js +2 -0
- package/dist/esm/plugins/police-blotter/index.js.map +1 -0
- package/dist/esm/plugins/police-blotter/phoenix-police.plugin.js +194 -0
- package/dist/esm/plugins/police-blotter/phoenix-police.plugin.js.map +1 -0
- package/dist/esm/plugins/pulsepoint/index.js +2 -0
- package/dist/esm/plugins/pulsepoint/index.js.map +1 -0
- package/dist/esm/plugins/pulsepoint/pulsepoint.plugin.js +271 -0
- package/dist/esm/plugins/pulsepoint/pulsepoint.plugin.js.map +1 -0
- package/dist/esm/plugins/traffic/arizona-traffic.plugin.js +387 -0
- package/dist/esm/plugins/traffic/arizona-traffic.plugin.js.map +1 -0
- package/dist/esm/plugins/traffic/index.js +2 -0
- package/dist/esm/plugins/traffic/index.js.map +1 -0
- package/dist/esm/plugins/weather/index.js +2 -0
- package/dist/esm/plugins/weather/index.js.map +1 -0
- package/dist/esm/plugins/weather/nws-weather.plugin.js +176 -0
- package/dist/esm/plugins/weather/nws-weather.plugin.js.map +1 -0
- package/dist/esm/schemas/alert.schema.js +90 -0
- package/dist/esm/schemas/alert.schema.js.map +1 -0
- package/dist/esm/schemas/index.js +5 -0
- package/dist/esm/schemas/index.js.map +1 -0
- package/dist/esm/schemas/query.schema.js +72 -0
- package/dist/esm/schemas/query.schema.js.map +1 -0
- package/dist/esm/types/alert.js +32 -0
- package/dist/esm/types/alert.js.map +1 -0
- package/dist/esm/types/config.js +10 -0
- package/dist/esm/types/config.js.map +1 -0
- package/dist/esm/types/geo.js +2 -0
- package/dist/esm/types/geo.js.map +1 -0
- package/dist/esm/types/index.js +4 -0
- package/dist/esm/types/index.js.map +1 -0
- package/dist/esm/types/plugin.js +2 -0
- package/dist/esm/types/plugin.js.map +1 -0
- package/dist/esm/types/query.js +25 -0
- package/dist/esm/types/query.js.map +1 -0
- package/dist/esm/utils/cache.js +181 -0
- package/dist/esm/utils/cache.js.map +1 -0
- package/dist/esm/utils/csv.js +185 -0
- package/dist/esm/utils/csv.js.map +1 -0
- package/dist/esm/utils/date.js +142 -0
- package/dist/esm/utils/date.js.map +1 -0
- package/dist/esm/utils/index.js +5 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/dist/esm/utils/retry.js +102 -0
- package/dist/esm/utils/retry.js.map +1 -0
- package/dist/types/adapters/index.d.ts +5 -0
- package/dist/types/adapters/index.d.ts.map +1 -0
- package/dist/types/adapters/lambda.d.ts +37 -0
- package/dist/types/adapters/lambda.d.ts.map +1 -0
- package/dist/types/adapters/vercel.d.ts +54 -0
- package/dist/types/adapters/vercel.d.ts.map +1 -0
- package/dist/types/core/alert-aggregator.d.ts +81 -0
- package/dist/types/core/alert-aggregator.d.ts.map +1 -0
- package/dist/types/core/alert-feed.d.ts +80 -0
- package/dist/types/core/alert-feed.d.ts.map +1 -0
- package/dist/types/core/index.d.ts +8 -0
- package/dist/types/core/index.d.ts.map +1 -0
- package/dist/types/core/plugin-registry.d.ts +91 -0
- package/dist/types/core/plugin-registry.d.ts.map +1 -0
- package/dist/types/core/plugin-resolver.d.ts +78 -0
- package/dist/types/core/plugin-resolver.d.ts.map +1 -0
- package/dist/types/core/time-range.d.ts +40 -0
- package/dist/types/core/time-range.d.ts.map +1 -0
- package/dist/types/errors/fetch-error.d.ts +46 -0
- package/dist/types/errors/fetch-error.d.ts.map +1 -0
- package/dist/types/errors/index.d.ts +5 -0
- package/dist/types/errors/index.d.ts.map +1 -0
- package/dist/types/errors/plugin-error.d.ts +42 -0
- package/dist/types/errors/plugin-error.d.ts.map +1 -0
- package/dist/types/errors/validation-error.d.ts +34 -0
- package/dist/types/errors/validation-error.d.ts.map +1 -0
- package/dist/types/geo/distance.d.ts +50 -0
- package/dist/types/geo/distance.d.ts.map +1 -0
- package/dist/types/geo/index.d.ts +3 -0
- package/dist/types/geo/index.d.ts.map +1 -0
- package/dist/types/geo/point-in-radius.d.ts +44 -0
- package/dist/types/geo/point-in-radius.d.ts.map +1 -0
- package/dist/types/index.d.ts +32 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/plugins/air-quality/airnow.plugin.d.ts +84 -0
- package/dist/types/plugins/air-quality/airnow.plugin.d.ts.map +1 -0
- package/dist/types/plugins/air-quality/index.d.ts +3 -0
- package/dist/types/plugins/air-quality/index.d.ts.map +1 -0
- package/dist/types/plugins/base-plugin.d.ts +99 -0
- package/dist/types/plugins/base-plugin.d.ts.map +1 -0
- package/dist/types/plugins/events/index.d.ts +3 -0
- package/dist/types/plugins/events/index.d.ts.map +1 -0
- package/dist/types/plugins/events/phoenix-events.plugin.d.ts +71 -0
- package/dist/types/plugins/events/phoenix-events.plugin.d.ts.map +1 -0
- package/dist/types/plugins/fire-emt/index.d.ts +3 -0
- package/dist/types/plugins/fire-emt/index.d.ts.map +1 -0
- package/dist/types/plugins/fire-emt/phoenix-fire.plugin.d.ts +47 -0
- package/dist/types/plugins/fire-emt/phoenix-fire.plugin.d.ts.map +1 -0
- package/dist/types/plugins/index.d.ts +17 -0
- package/dist/types/plugins/index.d.ts.map +1 -0
- package/dist/types/plugins/police-blotter/index.d.ts +3 -0
- package/dist/types/plugins/police-blotter/index.d.ts.map +1 -0
- package/dist/types/plugins/police-blotter/phoenix-police.plugin.d.ts +49 -0
- package/dist/types/plugins/police-blotter/phoenix-police.plugin.d.ts.map +1 -0
- package/dist/types/plugins/pulsepoint/index.d.ts +3 -0
- package/dist/types/plugins/pulsepoint/index.d.ts.map +1 -0
- package/dist/types/plugins/pulsepoint/pulsepoint.plugin.d.ts +61 -0
- package/dist/types/plugins/pulsepoint/pulsepoint.plugin.d.ts.map +1 -0
- package/dist/types/plugins/traffic/arizona-traffic.plugin.d.ts +83 -0
- package/dist/types/plugins/traffic/arizona-traffic.plugin.d.ts.map +1 -0
- package/dist/types/plugins/traffic/index.d.ts +3 -0
- package/dist/types/plugins/traffic/index.d.ts.map +1 -0
- package/dist/types/plugins/weather/index.d.ts +3 -0
- package/dist/types/plugins/weather/index.d.ts.map +1 -0
- package/dist/types/plugins/weather/nws-weather.plugin.d.ts +50 -0
- package/dist/types/plugins/weather/nws-weather.plugin.d.ts.map +1 -0
- package/dist/types/schemas/alert.schema.d.ts +266 -0
- package/dist/types/schemas/alert.schema.d.ts.map +1 -0
- package/dist/types/schemas/index.d.ts +5 -0
- package/dist/types/schemas/index.d.ts.map +1 -0
- package/dist/types/schemas/query.schema.d.ts +150 -0
- package/dist/types/schemas/query.schema.d.ts.map +1 -0
- package/dist/types/types/alert.d.ts +96 -0
- package/dist/types/types/alert.d.ts.map +1 -0
- package/dist/types/types/config.d.ts +63 -0
- package/dist/types/types/config.d.ts.map +1 -0
- package/dist/types/types/geo.d.ts +33 -0
- package/dist/types/types/geo.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +9 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/dist/types/types/plugin.d.ts +125 -0
- package/dist/types/types/plugin.d.ts.map +1 -0
- package/dist/types/types/query.d.ts +86 -0
- package/dist/types/types/query.d.ts.map +1 -0
- package/dist/types/utils/cache.d.ts +112 -0
- package/dist/types/utils/cache.d.ts.map +1 -0
- package/dist/types/utils/csv.d.ts +38 -0
- package/dist/types/utils/csv.d.ts.map +1 -0
- package/dist/types/utils/date.d.ts +47 -0
- package/dist/types/utils/date.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +7 -0
- package/dist/types/utils/index.d.ts.map +1 -0
- package/dist/types/utils/retry.d.ts +51 -0
- package/dist/types/utils/retry.d.ts.map +1 -0
- package/package.json +115 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createVercelHandler = exports.createLambdaHandler = void 0;
|
|
4
|
+
var lambda_1 = require("./lambda");
|
|
5
|
+
Object.defineProperty(exports, "createLambdaHandler", { enumerable: true, get: function () { return lambda_1.createLambdaHandler; } });
|
|
6
|
+
var vercel_1 = require("./vercel");
|
|
7
|
+
Object.defineProperty(exports, "createVercelHandler", { enumerable: true, get: function () { return vercel_1.createVercelHandler; } });
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/index.ts"],"names":[],"mappings":";;;AAAA,mCAA+C;AAAtC,6GAAA,mBAAmB,OAAA;AAG5B,mCAA+C;AAAtC,6GAAA,mBAAmB,OAAA"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createLambdaHandler = createLambdaHandler;
|
|
4
|
+
const core_1 = require("../core");
|
|
5
|
+
const schemas_1 = require("../schemas");
|
|
6
|
+
const errors_1 = require("../errors");
|
|
7
|
+
/**
|
|
8
|
+
* Create an AWS Lambda handler for the AlertFeed.
|
|
9
|
+
*
|
|
10
|
+
* Supports both GET (query parameters) and POST (JSON body) requests.
|
|
11
|
+
*
|
|
12
|
+
* @param options - Handler configuration options
|
|
13
|
+
* @returns Lambda handler function
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { createLambdaHandler } from 'local-risk-alert-feed/adapters/lambda';
|
|
18
|
+
* import { PhoenixPolicePlugin } from 'local-risk-alert-feed/plugins/police-blotter';
|
|
19
|
+
*
|
|
20
|
+
* export const handler = createLambdaHandler({
|
|
21
|
+
* plugins: [{ plugin: new PhoenixPolicePlugin() }]
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
function createLambdaHandler(options) {
|
|
26
|
+
const feed = new core_1.AlertFeed(options);
|
|
27
|
+
const corsOrigin = options.corsOrigin ?? '*';
|
|
28
|
+
const corsHeaders = [
|
|
29
|
+
'Content-Type',
|
|
30
|
+
'Authorization',
|
|
31
|
+
...(options.corsHeaders ?? []),
|
|
32
|
+
].join(', ');
|
|
33
|
+
const corsMethods = ['GET', 'POST', 'OPTIONS', ...(options.corsMethods ?? [])].join(', ');
|
|
34
|
+
// Initialize plugins
|
|
35
|
+
if (options.plugins) {
|
|
36
|
+
feed.registerPlugins(options.plugins).catch(console.error);
|
|
37
|
+
}
|
|
38
|
+
return async (event, _context) => {
|
|
39
|
+
// Handle CORS preflight
|
|
40
|
+
if (event.httpMethod === 'OPTIONS') {
|
|
41
|
+
return createCorsResponse(corsOrigin, corsHeaders, corsMethods);
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
// Parse request
|
|
45
|
+
const requestData = parseRequest(event);
|
|
46
|
+
// Validate request
|
|
47
|
+
const parseResult = schemas_1.AlertQueryRequestSchema.safeParse(requestData);
|
|
48
|
+
if (!parseResult.success) {
|
|
49
|
+
return createErrorResponse(400, 'Validation Error', errors_1.ValidationError.fromZodError(parseResult.error).toJSON(), corsOrigin);
|
|
50
|
+
}
|
|
51
|
+
// Transform to query
|
|
52
|
+
const query = (0, schemas_1.transformRequestToQuery)(parseResult.data);
|
|
53
|
+
// Execute query
|
|
54
|
+
const response = await feed.query(query);
|
|
55
|
+
return createSuccessResponse(response, corsOrigin);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
console.error('AlertFeed error:', error);
|
|
59
|
+
if (error instanceof errors_1.ValidationError) {
|
|
60
|
+
return createErrorResponse(400, 'Validation Error', error.toJSON(), corsOrigin);
|
|
61
|
+
}
|
|
62
|
+
return createErrorResponse(500, 'Internal Server Error', {
|
|
63
|
+
message: error instanceof Error ? error.message : 'An unexpected error occurred',
|
|
64
|
+
}, corsOrigin);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Parse request data from Lambda event.
|
|
70
|
+
*/
|
|
71
|
+
function parseRequest(event) {
|
|
72
|
+
if (event.httpMethod === 'POST' && event.body) {
|
|
73
|
+
try {
|
|
74
|
+
return JSON.parse(event.body);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
throw new errors_1.ValidationError('Invalid JSON body', [
|
|
78
|
+
{ path: 'body', message: 'Request body must be valid JSON', code: 'invalid_type' },
|
|
79
|
+
]);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Parse from query parameters
|
|
83
|
+
const params = event.queryStringParameters ?? {};
|
|
84
|
+
const multiParams = event.multiValueQueryStringParameters ?? {};
|
|
85
|
+
return {
|
|
86
|
+
latitude: params.latitude ? parseFloat(params.latitude) : undefined,
|
|
87
|
+
longitude: params.longitude ? parseFloat(params.longitude) : undefined,
|
|
88
|
+
radiusMeters: params.radiusMeters ? parseFloat(params.radiusMeters) : undefined,
|
|
89
|
+
limit: params.limit ? parseInt(params.limit, 10) : undefined,
|
|
90
|
+
minRiskLevel: params.minRiskLevel,
|
|
91
|
+
timeRange: params.timeRange,
|
|
92
|
+
categories: multiParams.categories ?? (params.categories ? [params.categories] : undefined),
|
|
93
|
+
temporalTypes: multiParams.temporalTypes ?? (params.temporalTypes ? [params.temporalTypes] : undefined),
|
|
94
|
+
includePluginResults: params.includePluginResults === 'true',
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Create a success response.
|
|
99
|
+
*/
|
|
100
|
+
function createSuccessResponse(data, corsOrigin) {
|
|
101
|
+
return {
|
|
102
|
+
statusCode: 200,
|
|
103
|
+
headers: getCorsHeaders(corsOrigin),
|
|
104
|
+
body: JSON.stringify(data),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Create an error response.
|
|
109
|
+
*/
|
|
110
|
+
function createErrorResponse(statusCode, error, details, corsOrigin) {
|
|
111
|
+
return {
|
|
112
|
+
statusCode,
|
|
113
|
+
headers: getCorsHeaders(corsOrigin),
|
|
114
|
+
body: JSON.stringify({ error, ...details }),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Create a CORS preflight response.
|
|
119
|
+
*/
|
|
120
|
+
function createCorsResponse(corsOrigin, corsHeaders, corsMethods) {
|
|
121
|
+
const origin = Array.isArray(corsOrigin) ? corsOrigin[0] : corsOrigin;
|
|
122
|
+
return {
|
|
123
|
+
statusCode: 204,
|
|
124
|
+
headers: {
|
|
125
|
+
'Access-Control-Allow-Origin': origin,
|
|
126
|
+
'Access-Control-Allow-Headers': corsHeaders,
|
|
127
|
+
'Access-Control-Allow-Methods': corsMethods,
|
|
128
|
+
'Access-Control-Max-Age': '86400',
|
|
129
|
+
},
|
|
130
|
+
body: '',
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get CORS headers for response.
|
|
135
|
+
*/
|
|
136
|
+
function getCorsHeaders(corsOrigin) {
|
|
137
|
+
const origin = Array.isArray(corsOrigin) ? corsOrigin[0] : corsOrigin;
|
|
138
|
+
return {
|
|
139
|
+
'Content-Type': 'application/json',
|
|
140
|
+
'Access-Control-Allow-Origin': origin,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=lambda.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lambda.js","sourceRoot":"","sources":["../../../src/adapters/lambda.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createVercelHandler = createVercelHandler;
|
|
4
|
+
const core_1 = require("../core");
|
|
5
|
+
const schemas_1 = require("../schemas");
|
|
6
|
+
const errors_1 = require("../errors");
|
|
7
|
+
/**
|
|
8
|
+
* Create Next.js App Router handlers for the AlertFeed.
|
|
9
|
+
*
|
|
10
|
+
* Returns GET and POST handlers that can be exported from a route file.
|
|
11
|
+
*
|
|
12
|
+
* @param options - Handler configuration options
|
|
13
|
+
* @returns Object with GET and POST handlers
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* // app/api/alerts/route.ts
|
|
18
|
+
* import { createVercelHandler } from 'local-risk-alert-feed/adapters/vercel';
|
|
19
|
+
* import { PhoenixPolicePlugin } from 'local-risk-alert-feed/plugins/police-blotter';
|
|
20
|
+
*
|
|
21
|
+
* const { GET, POST } = createVercelHandler({
|
|
22
|
+
* plugins: [{ plugin: new PhoenixPolicePlugin() }]
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* export { GET, POST };
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
function createVercelHandler(options) {
|
|
29
|
+
const feed = new core_1.AlertFeed(options);
|
|
30
|
+
const corsOrigin = options.corsOrigin ?? '*';
|
|
31
|
+
// Initialize plugins
|
|
32
|
+
if (options.plugins) {
|
|
33
|
+
feed.registerPlugins(options.plugins).catch(console.error);
|
|
34
|
+
}
|
|
35
|
+
const handleRequest = async (request) => {
|
|
36
|
+
try {
|
|
37
|
+
// Parse request
|
|
38
|
+
const requestData = await parseRequest(request);
|
|
39
|
+
// Validate request
|
|
40
|
+
const parseResult = schemas_1.AlertQueryRequestSchema.safeParse(requestData);
|
|
41
|
+
if (!parseResult.success) {
|
|
42
|
+
return createErrorResponse(400, 'Validation Error', errors_1.ValidationError.fromZodError(parseResult.error).toJSON(), corsOrigin);
|
|
43
|
+
}
|
|
44
|
+
// Transform to query
|
|
45
|
+
const query = (0, schemas_1.transformRequestToQuery)(parseResult.data);
|
|
46
|
+
// Execute query
|
|
47
|
+
const response = await feed.query(query);
|
|
48
|
+
return createSuccessResponse(response, corsOrigin);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
console.error('AlertFeed error:', error);
|
|
52
|
+
if (error instanceof errors_1.ValidationError) {
|
|
53
|
+
return createErrorResponse(400, 'Validation Error', error.toJSON(), corsOrigin);
|
|
54
|
+
}
|
|
55
|
+
return createErrorResponse(500, 'Internal Server Error', {
|
|
56
|
+
message: error instanceof Error ? error.message : 'An unexpected error occurred',
|
|
57
|
+
}, corsOrigin);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
return {
|
|
61
|
+
GET: handleRequest,
|
|
62
|
+
POST: handleRequest,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Parse request data from Next.js request.
|
|
67
|
+
*/
|
|
68
|
+
async function parseRequest(request) {
|
|
69
|
+
if (request.method === 'POST') {
|
|
70
|
+
try {
|
|
71
|
+
return (await request.json());
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
throw new errors_1.ValidationError('Invalid JSON body', [
|
|
75
|
+
{ path: 'body', message: 'Request body must be valid JSON', code: 'invalid_type' },
|
|
76
|
+
]);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Parse from query parameters
|
|
80
|
+
const params = request.nextUrl.searchParams;
|
|
81
|
+
return {
|
|
82
|
+
latitude: params.has('latitude') ? parseFloat(params.get('latitude')) : undefined,
|
|
83
|
+
longitude: params.has('longitude') ? parseFloat(params.get('longitude')) : undefined,
|
|
84
|
+
radiusMeters: params.has('radiusMeters') ? parseFloat(params.get('radiusMeters')) : undefined,
|
|
85
|
+
limit: params.has('limit') ? parseInt(params.get('limit'), 10) : undefined,
|
|
86
|
+
minRiskLevel: params.get('minRiskLevel') ?? undefined,
|
|
87
|
+
timeRange: params.get('timeRange') ?? undefined,
|
|
88
|
+
categories: params.getAll('categories').length > 0 ? params.getAll('categories') : undefined,
|
|
89
|
+
temporalTypes: params.getAll('temporalTypes').length > 0 ? params.getAll('temporalTypes') : undefined,
|
|
90
|
+
includePluginResults: params.get('includePluginResults') === 'true',
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Create a success response.
|
|
95
|
+
*/
|
|
96
|
+
function createSuccessResponse(data, corsOrigin) {
|
|
97
|
+
const origin = Array.isArray(corsOrigin) ? corsOrigin[0] : corsOrigin;
|
|
98
|
+
return new Response(JSON.stringify(data), {
|
|
99
|
+
status: 200,
|
|
100
|
+
headers: {
|
|
101
|
+
'Content-Type': 'application/json',
|
|
102
|
+
'Access-Control-Allow-Origin': origin,
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Create an error response.
|
|
108
|
+
*/
|
|
109
|
+
function createErrorResponse(statusCode, error, details, corsOrigin) {
|
|
110
|
+
const origin = Array.isArray(corsOrigin) ? corsOrigin[0] : corsOrigin;
|
|
111
|
+
return new Response(JSON.stringify({ error, ...details }), {
|
|
112
|
+
status: statusCode,
|
|
113
|
+
headers: {
|
|
114
|
+
'Content-Type': 'application/json',
|
|
115
|
+
'Access-Control-Allow-Origin': origin,
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
//# 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,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AlertAggregator = void 0;
|
|
4
|
+
const types_1 = require("../types");
|
|
5
|
+
const geo_1 = require("../geo");
|
|
6
|
+
/**
|
|
7
|
+
* Aggregates, filters, deduplicates, and sorts alerts from multiple sources.
|
|
8
|
+
*/
|
|
9
|
+
class AlertAggregator {
|
|
10
|
+
/**
|
|
11
|
+
* Aggregate alerts from multiple sources.
|
|
12
|
+
*
|
|
13
|
+
* Combines alerts, removes duplicates, filters by criteria, and sorts.
|
|
14
|
+
*
|
|
15
|
+
* @param alertSets - Arrays of alerts from different plugins
|
|
16
|
+
* @param options - Aggregation options
|
|
17
|
+
* @returns Aggregated and filtered alerts
|
|
18
|
+
*/
|
|
19
|
+
aggregate(alertSets, options = {}) {
|
|
20
|
+
// Flatten all alerts
|
|
21
|
+
let alerts = alertSets.flat();
|
|
22
|
+
// Deduplicate
|
|
23
|
+
alerts = this.deduplicate(alerts);
|
|
24
|
+
// Filter by risk level
|
|
25
|
+
if (options.minRiskLevel) {
|
|
26
|
+
alerts = this.filterByRiskLevel(alerts, options.minRiskLevel);
|
|
27
|
+
}
|
|
28
|
+
// Filter by time range
|
|
29
|
+
if (options.timeRange) {
|
|
30
|
+
alerts = this.filterByTimeRange(alerts, options.timeRange);
|
|
31
|
+
}
|
|
32
|
+
// Filter by location radius
|
|
33
|
+
if (options.location && options.radiusMeters) {
|
|
34
|
+
alerts = this.filterByRadius(alerts, options.location, options.radiusMeters);
|
|
35
|
+
}
|
|
36
|
+
// Sort by priority (primary) and time (secondary)
|
|
37
|
+
alerts = this.sort(alerts, ['priority-asc', 'time-desc']);
|
|
38
|
+
// Apply limit
|
|
39
|
+
if (options.limit && alerts.length > options.limit) {
|
|
40
|
+
alerts = alerts.slice(0, options.limit);
|
|
41
|
+
}
|
|
42
|
+
return alerts;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Remove duplicate alerts based on ID and source.
|
|
46
|
+
*
|
|
47
|
+
* If two alerts have the same external ID from the same source,
|
|
48
|
+
* keep the one with the most recent issued timestamp.
|
|
49
|
+
*/
|
|
50
|
+
deduplicate(alerts) {
|
|
51
|
+
const seen = new Map();
|
|
52
|
+
for (const alert of alerts) {
|
|
53
|
+
// Primary dedup key: alert ID
|
|
54
|
+
const primaryKey = alert.id;
|
|
55
|
+
// Secondary dedup key: source external ID (if available)
|
|
56
|
+
const secondaryKey = alert.source.externalId
|
|
57
|
+
? `${alert.source.pluginId}:${alert.source.externalId}`
|
|
58
|
+
: null;
|
|
59
|
+
// Check primary key
|
|
60
|
+
const existingPrimary = seen.get(primaryKey);
|
|
61
|
+
if (existingPrimary) {
|
|
62
|
+
// Keep the more recent one
|
|
63
|
+
if (new Date(alert.timestamps.issued) > new Date(existingPrimary.timestamps.issued)) {
|
|
64
|
+
seen.set(primaryKey, alert);
|
|
65
|
+
}
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
// Check secondary key
|
|
69
|
+
if (secondaryKey) {
|
|
70
|
+
const existingSecondary = seen.get(secondaryKey);
|
|
71
|
+
if (existingSecondary) {
|
|
72
|
+
if (new Date(alert.timestamps.issued) > new Date(existingSecondary.timestamps.issued)) {
|
|
73
|
+
seen.set(secondaryKey, alert);
|
|
74
|
+
}
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
seen.set(secondaryKey, alert);
|
|
78
|
+
}
|
|
79
|
+
seen.set(primaryKey, alert);
|
|
80
|
+
}
|
|
81
|
+
return Array.from(seen.values());
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Filter alerts by minimum risk level.
|
|
85
|
+
*/
|
|
86
|
+
filterByRiskLevel(alerts, minLevel) {
|
|
87
|
+
const minValue = types_1.RISK_LEVEL_VALUES[minLevel];
|
|
88
|
+
return alerts.filter((alert) => types_1.RISK_LEVEL_VALUES[alert.riskLevel] >= minValue);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Filter alerts by time range.
|
|
92
|
+
*
|
|
93
|
+
* Includes alerts where:
|
|
94
|
+
* - The issued timestamp falls within the range, OR
|
|
95
|
+
* - The event start/end times overlap with the range
|
|
96
|
+
*/
|
|
97
|
+
filterByTimeRange(alerts, range) {
|
|
98
|
+
const rangeStart = new Date(range.start).getTime();
|
|
99
|
+
const rangeEnd = new Date(range.end).getTime();
|
|
100
|
+
return alerts.filter((alert) => {
|
|
101
|
+
// Check if issued time is in range
|
|
102
|
+
const issuedTime = new Date(alert.timestamps.issued).getTime();
|
|
103
|
+
if (issuedTime >= rangeStart && issuedTime <= rangeEnd) {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
// Check if event times overlap
|
|
107
|
+
const eventStart = alert.timestamps.eventStart
|
|
108
|
+
? new Date(alert.timestamps.eventStart).getTime()
|
|
109
|
+
: null;
|
|
110
|
+
const eventEnd = alert.timestamps.eventEnd
|
|
111
|
+
? new Date(alert.timestamps.eventEnd).getTime()
|
|
112
|
+
: null;
|
|
113
|
+
if (eventStart !== null && eventEnd !== null) {
|
|
114
|
+
// Event has both start and end - check for overlap
|
|
115
|
+
return eventStart <= rangeEnd && eventEnd >= rangeStart;
|
|
116
|
+
}
|
|
117
|
+
if (eventStart !== null) {
|
|
118
|
+
// Only start time - check if it's in range
|
|
119
|
+
return eventStart >= rangeStart && eventStart <= rangeEnd;
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Filter alerts by distance from a center point.
|
|
126
|
+
*/
|
|
127
|
+
filterByRadius(alerts, center, radiusMeters) {
|
|
128
|
+
return alerts.filter((alert) => {
|
|
129
|
+
const distance = (0, geo_1.haversineDistance)(center, alert.location.point);
|
|
130
|
+
return distance <= radiusMeters;
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Sort alerts by one or more criteria.
|
|
135
|
+
*
|
|
136
|
+
* Later criteria are used as tiebreakers.
|
|
137
|
+
*/
|
|
138
|
+
sort(alerts, orders) {
|
|
139
|
+
return [...alerts].sort((a, b) => {
|
|
140
|
+
for (const order of orders) {
|
|
141
|
+
const comparison = this.compare(a, b, order);
|
|
142
|
+
if (comparison !== 0)
|
|
143
|
+
return comparison;
|
|
144
|
+
}
|
|
145
|
+
return 0;
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Compare two alerts based on a sort order.
|
|
150
|
+
*/
|
|
151
|
+
compare(a, b, order) {
|
|
152
|
+
switch (order) {
|
|
153
|
+
case 'priority-asc':
|
|
154
|
+
return a.priority - b.priority;
|
|
155
|
+
case 'priority-desc':
|
|
156
|
+
return b.priority - a.priority;
|
|
157
|
+
case 'risk-asc':
|
|
158
|
+
return types_1.RISK_LEVEL_VALUES[a.riskLevel] - types_1.RISK_LEVEL_VALUES[b.riskLevel];
|
|
159
|
+
case 'risk-desc':
|
|
160
|
+
return types_1.RISK_LEVEL_VALUES[b.riskLevel] - types_1.RISK_LEVEL_VALUES[a.riskLevel];
|
|
161
|
+
case 'time-asc':
|
|
162
|
+
return new Date(a.timestamps.issued).getTime() - new Date(b.timestamps.issued).getTime();
|
|
163
|
+
case 'time-desc':
|
|
164
|
+
return new Date(b.timestamps.issued).getTime() - new Date(a.timestamps.issued).getTime();
|
|
165
|
+
case 'distance-asc':
|
|
166
|
+
case 'distance-desc':
|
|
167
|
+
// Distance sorting requires a reference point, not supported in basic compare
|
|
168
|
+
return 0;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Sort alerts by distance from a center point.
|
|
173
|
+
*/
|
|
174
|
+
sortByDistance(alerts, center, ascending = true) {
|
|
175
|
+
return [...alerts].sort((a, b) => {
|
|
176
|
+
const distA = (0, geo_1.haversineDistance)(center, a.location.point);
|
|
177
|
+
const distB = (0, geo_1.haversineDistance)(center, b.location.point);
|
|
178
|
+
return ascending ? distA - distB : distB - distA;
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Group alerts by category.
|
|
183
|
+
*/
|
|
184
|
+
groupByCategory(alerts) {
|
|
185
|
+
const groups = new Map();
|
|
186
|
+
for (const alert of alerts) {
|
|
187
|
+
const existing = groups.get(alert.category) ?? [];
|
|
188
|
+
existing.push(alert);
|
|
189
|
+
groups.set(alert.category, existing);
|
|
190
|
+
}
|
|
191
|
+
return groups;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Group alerts by source plugin.
|
|
195
|
+
*/
|
|
196
|
+
groupBySource(alerts) {
|
|
197
|
+
const groups = new Map();
|
|
198
|
+
for (const alert of alerts) {
|
|
199
|
+
const existing = groups.get(alert.source.pluginId) ?? [];
|
|
200
|
+
existing.push(alert);
|
|
201
|
+
groups.set(alert.source.pluginId, existing);
|
|
202
|
+
}
|
|
203
|
+
return groups;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
exports.AlertAggregator = AlertAggregator;
|
|
207
|
+
//# 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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"}
|