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,189 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Simple CSV parser for handling Phoenix Open Data CSV responses.
|
|
4
|
+
*
|
|
5
|
+
* This is a lightweight parser that handles:
|
|
6
|
+
* - Quoted fields with commas
|
|
7
|
+
* - Escaped quotes within fields
|
|
8
|
+
* - Header row parsing
|
|
9
|
+
* - Type coercion for common patterns
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.parseCSV = parseCSV;
|
|
13
|
+
exports.toCSV = toCSV;
|
|
14
|
+
/**
|
|
15
|
+
* Parse a CSV string into an array of objects.
|
|
16
|
+
*
|
|
17
|
+
* @param csvText - The raw CSV text
|
|
18
|
+
* @param options - Parser options
|
|
19
|
+
* @returns Array of parsed objects with headers as keys
|
|
20
|
+
*/
|
|
21
|
+
function parseCSV(csvText, options = {}) {
|
|
22
|
+
const { delimiter = ',', hasHeader = true, trimFields = true } = options;
|
|
23
|
+
const lines = splitCSVLines(csvText);
|
|
24
|
+
if (lines.length === 0) {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
const headerLine = hasHeader ? lines[0] : null;
|
|
28
|
+
const dataLines = hasHeader ? lines.slice(1) : lines;
|
|
29
|
+
const headers = headerLine
|
|
30
|
+
? parseCSVLine(headerLine, delimiter).map((h) => (trimFields ? h.trim() : h))
|
|
31
|
+
: [];
|
|
32
|
+
const results = [];
|
|
33
|
+
for (const line of dataLines) {
|
|
34
|
+
if (line.trim() === '')
|
|
35
|
+
continue;
|
|
36
|
+
const values = parseCSVLine(line, delimiter);
|
|
37
|
+
const obj = {};
|
|
38
|
+
for (let i = 0; i < values.length; i++) {
|
|
39
|
+
const key = headers[i] ?? `column_${i}`;
|
|
40
|
+
let value = trimFields ? values[i].trim() : values[i];
|
|
41
|
+
// Type coercion for common patterns
|
|
42
|
+
if (options.coerceTypes !== false) {
|
|
43
|
+
value = coerceValue(value);
|
|
44
|
+
}
|
|
45
|
+
obj[key] = value;
|
|
46
|
+
}
|
|
47
|
+
results.push(obj);
|
|
48
|
+
}
|
|
49
|
+
return results;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Split CSV text into lines, handling quoted newlines.
|
|
53
|
+
*/
|
|
54
|
+
function splitCSVLines(text) {
|
|
55
|
+
const lines = [];
|
|
56
|
+
let currentLine = '';
|
|
57
|
+
let inQuotes = false;
|
|
58
|
+
for (let i = 0; i < text.length; i++) {
|
|
59
|
+
const char = text[i];
|
|
60
|
+
if (char === '"') {
|
|
61
|
+
// Check for escaped quote
|
|
62
|
+
if (inQuotes && text[i + 1] === '"') {
|
|
63
|
+
currentLine += '""';
|
|
64
|
+
i++;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
inQuotes = !inQuotes;
|
|
68
|
+
currentLine += char;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else if ((char === '\n' || char === '\r') && !inQuotes) {
|
|
72
|
+
// End of line
|
|
73
|
+
if (currentLine.length > 0) {
|
|
74
|
+
lines.push(currentLine);
|
|
75
|
+
}
|
|
76
|
+
currentLine = '';
|
|
77
|
+
// Skip \r\n as single line ending
|
|
78
|
+
if (char === '\r' && text[i + 1] === '\n') {
|
|
79
|
+
i++;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
currentLine += char;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Add final line if exists
|
|
87
|
+
if (currentLine.length > 0) {
|
|
88
|
+
lines.push(currentLine);
|
|
89
|
+
}
|
|
90
|
+
return lines;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Parse a single CSV line into fields.
|
|
94
|
+
*/
|
|
95
|
+
function parseCSVLine(line, delimiter) {
|
|
96
|
+
const fields = [];
|
|
97
|
+
let currentField = '';
|
|
98
|
+
let inQuotes = false;
|
|
99
|
+
for (let i = 0; i < line.length; i++) {
|
|
100
|
+
const char = line[i];
|
|
101
|
+
if (char === '"') {
|
|
102
|
+
if (inQuotes && line[i + 1] === '"') {
|
|
103
|
+
// Escaped quote
|
|
104
|
+
currentField += '"';
|
|
105
|
+
i++;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
// Toggle quote mode
|
|
109
|
+
inQuotes = !inQuotes;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else if (char === delimiter && !inQuotes) {
|
|
113
|
+
// End of field
|
|
114
|
+
fields.push(currentField);
|
|
115
|
+
currentField = '';
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
currentField += char;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Add final field
|
|
122
|
+
fields.push(currentField);
|
|
123
|
+
return fields;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Attempt to coerce a string value to a more specific type.
|
|
127
|
+
*/
|
|
128
|
+
function coerceValue(value) {
|
|
129
|
+
// Empty or null-like values
|
|
130
|
+
if (value === '' || value.toLowerCase() === 'null' || value.toLowerCase() === 'undefined') {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
// Boolean
|
|
134
|
+
if (value.toLowerCase() === 'true')
|
|
135
|
+
return true;
|
|
136
|
+
if (value.toLowerCase() === 'false')
|
|
137
|
+
return false;
|
|
138
|
+
// Number (integer or float)
|
|
139
|
+
if (/^-?\d+$/.test(value)) {
|
|
140
|
+
const num = parseInt(value, 10);
|
|
141
|
+
if (!isNaN(num) && num >= Number.MIN_SAFE_INTEGER && num <= Number.MAX_SAFE_INTEGER) {
|
|
142
|
+
return num;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (/^-?\d*\.\d+$/.test(value)) {
|
|
146
|
+
const num = parseFloat(value);
|
|
147
|
+
if (!isNaN(num)) {
|
|
148
|
+
return num;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// Return as string
|
|
152
|
+
return value;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Convert an array of objects to CSV string.
|
|
156
|
+
*/
|
|
157
|
+
function toCSV(data, options = {}) {
|
|
158
|
+
if (data.length === 0)
|
|
159
|
+
return '';
|
|
160
|
+
const { delimiter = ',' } = options;
|
|
161
|
+
const headers = options.headers ?? Object.keys(data[0]);
|
|
162
|
+
const lines = [];
|
|
163
|
+
// Header row
|
|
164
|
+
lines.push(headers.map((h) => escapeCSVField(String(h), delimiter)).join(delimiter));
|
|
165
|
+
// Data rows
|
|
166
|
+
for (const row of data) {
|
|
167
|
+
const values = headers.map((h) => {
|
|
168
|
+
const value = row[h];
|
|
169
|
+
if (value === null || value === undefined)
|
|
170
|
+
return '';
|
|
171
|
+
return escapeCSVField(String(value), delimiter);
|
|
172
|
+
});
|
|
173
|
+
lines.push(values.join(delimiter));
|
|
174
|
+
}
|
|
175
|
+
return lines.join('\n');
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Escape a field for CSV output.
|
|
179
|
+
*/
|
|
180
|
+
function escapeCSVField(value, delimiter) {
|
|
181
|
+
// Check if quoting is needed
|
|
182
|
+
if (value.includes('"') || value.includes(delimiter) || value.includes('\n') || value.includes('\r')) {
|
|
183
|
+
// Escape quotes by doubling them
|
|
184
|
+
const escaped = value.replace(/"/g, '""');
|
|
185
|
+
return `"${escaped}"`;
|
|
186
|
+
}
|
|
187
|
+
return value;
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=csv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csv.js","sourceRoot":"","sources":["../../../src/utils/csv.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DAY_MS = exports.HOUR_MS = void 0;
|
|
4
|
+
exports.isTimeRangePreset = isTimeRangePreset;
|
|
5
|
+
exports.isTimeRange = isTimeRange;
|
|
6
|
+
exports.resolveTimeRange = resolveTimeRange;
|
|
7
|
+
exports.resolveTimeRangePreset = resolveTimeRangePreset;
|
|
8
|
+
exports.isDateInRange = isDateInRange;
|
|
9
|
+
exports.doRangesOverlap = doRangesOverlap;
|
|
10
|
+
exports.formatDuration = formatDuration;
|
|
11
|
+
exports.parseISODate = parseISODate;
|
|
12
|
+
/**
|
|
13
|
+
* Duration constants in milliseconds.
|
|
14
|
+
*/
|
|
15
|
+
exports.HOUR_MS = 60 * 60 * 1000;
|
|
16
|
+
exports.DAY_MS = 24 * exports.HOUR_MS;
|
|
17
|
+
/**
|
|
18
|
+
* Check if a string is a valid TimeRangePreset.
|
|
19
|
+
*/
|
|
20
|
+
function isTimeRangePreset(value) {
|
|
21
|
+
return [
|
|
22
|
+
'past-24h',
|
|
23
|
+
'past-7d',
|
|
24
|
+
'past-30d',
|
|
25
|
+
'next-4h',
|
|
26
|
+
'next-12h',
|
|
27
|
+
'next-24h',
|
|
28
|
+
'next-7d',
|
|
29
|
+
].includes(value);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Check if an object is a TimeRange.
|
|
33
|
+
*/
|
|
34
|
+
function isTimeRange(value) {
|
|
35
|
+
return (typeof value === 'object' &&
|
|
36
|
+
value !== null &&
|
|
37
|
+
'start' in value &&
|
|
38
|
+
'end' in value &&
|
|
39
|
+
typeof value.start === 'string' &&
|
|
40
|
+
typeof value.end === 'string');
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Resolve a TimeRangeInput to an explicit TimeRange.
|
|
44
|
+
*
|
|
45
|
+
* @param input - Either a preset string or explicit time range
|
|
46
|
+
* @param now - Optional reference time (defaults to current time)
|
|
47
|
+
* @returns Resolved TimeRange with start and end as ISO strings
|
|
48
|
+
*/
|
|
49
|
+
function resolveTimeRange(input, now) {
|
|
50
|
+
const reference = now ?? new Date();
|
|
51
|
+
// Default to next-24h if no input provided
|
|
52
|
+
if (!input) {
|
|
53
|
+
return resolveTimeRangePreset('next-24h', reference);
|
|
54
|
+
}
|
|
55
|
+
// If it's already a TimeRange, return it
|
|
56
|
+
if (isTimeRange(input)) {
|
|
57
|
+
return input;
|
|
58
|
+
}
|
|
59
|
+
// Otherwise it's a preset
|
|
60
|
+
return resolveTimeRangePreset(input, reference);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Resolve a TimeRangePreset to an explicit TimeRange.
|
|
64
|
+
*/
|
|
65
|
+
function resolveTimeRangePreset(preset, now) {
|
|
66
|
+
const reference = now.getTime();
|
|
67
|
+
switch (preset) {
|
|
68
|
+
case 'past-24h':
|
|
69
|
+
return {
|
|
70
|
+
start: new Date(reference - exports.DAY_MS).toISOString(),
|
|
71
|
+
end: now.toISOString(),
|
|
72
|
+
};
|
|
73
|
+
case 'past-7d':
|
|
74
|
+
return {
|
|
75
|
+
start: new Date(reference - 7 * exports.DAY_MS).toISOString(),
|
|
76
|
+
end: now.toISOString(),
|
|
77
|
+
};
|
|
78
|
+
case 'past-30d':
|
|
79
|
+
return {
|
|
80
|
+
start: new Date(reference - 30 * exports.DAY_MS).toISOString(),
|
|
81
|
+
end: now.toISOString(),
|
|
82
|
+
};
|
|
83
|
+
case 'next-4h':
|
|
84
|
+
return {
|
|
85
|
+
start: now.toISOString(),
|
|
86
|
+
end: new Date(reference + 4 * exports.HOUR_MS).toISOString(),
|
|
87
|
+
};
|
|
88
|
+
case 'next-12h':
|
|
89
|
+
return {
|
|
90
|
+
start: now.toISOString(),
|
|
91
|
+
end: new Date(reference + 12 * exports.HOUR_MS).toISOString(),
|
|
92
|
+
};
|
|
93
|
+
case 'next-24h':
|
|
94
|
+
return {
|
|
95
|
+
start: now.toISOString(),
|
|
96
|
+
end: new Date(reference + exports.DAY_MS).toISOString(),
|
|
97
|
+
};
|
|
98
|
+
case 'next-7d':
|
|
99
|
+
return {
|
|
100
|
+
start: now.toISOString(),
|
|
101
|
+
end: new Date(reference + 7 * exports.DAY_MS).toISOString(),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Check if a date falls within a time range.
|
|
107
|
+
*
|
|
108
|
+
* @param date - The date to check (string or Date)
|
|
109
|
+
* @param range - The time range to check against
|
|
110
|
+
* @returns true if the date falls within the range (inclusive)
|
|
111
|
+
*/
|
|
112
|
+
function isDateInRange(date, range) {
|
|
113
|
+
const timestamp = typeof date === 'string' ? new Date(date).getTime() : date.getTime();
|
|
114
|
+
const start = new Date(range.start).getTime();
|
|
115
|
+
const end = new Date(range.end).getTime();
|
|
116
|
+
return timestamp >= start && timestamp <= end;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Check if two time ranges overlap.
|
|
120
|
+
*/
|
|
121
|
+
function doRangesOverlap(range1, range2) {
|
|
122
|
+
const start1 = new Date(range1.start).getTime();
|
|
123
|
+
const end1 = new Date(range1.end).getTime();
|
|
124
|
+
const start2 = new Date(range2.start).getTime();
|
|
125
|
+
const end2 = new Date(range2.end).getTime();
|
|
126
|
+
return start1 <= end2 && start2 <= end1;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Format a duration in milliseconds to a human-readable string.
|
|
130
|
+
*/
|
|
131
|
+
function formatDuration(ms) {
|
|
132
|
+
if (ms < 1000) {
|
|
133
|
+
return `${ms}ms`;
|
|
134
|
+
}
|
|
135
|
+
if (ms < 60_000) {
|
|
136
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
137
|
+
}
|
|
138
|
+
if (ms < exports.HOUR_MS) {
|
|
139
|
+
return `${(ms / 60_000).toFixed(1)}m`;
|
|
140
|
+
}
|
|
141
|
+
if (ms < exports.DAY_MS) {
|
|
142
|
+
return `${(ms / exports.HOUR_MS).toFixed(1)}h`;
|
|
143
|
+
}
|
|
144
|
+
return `${(ms / exports.DAY_MS).toFixed(1)}d`;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Parse an ISO date string to a Date object, returning null if invalid.
|
|
148
|
+
*/
|
|
149
|
+
function parseISODate(dateString) {
|
|
150
|
+
const date = new Date(dateString);
|
|
151
|
+
return isNaN(date.getTime()) ? null : date;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=date.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date.js","sourceRoot":"","sources":["../../../src/utils/date.ts"],"names":[],"mappings":";;;AAWA,8CAUC;AAKD,kCASC;AASD,4CAeC;AAKD,wDAwCC;AASD,sCAMC;AAKD,0CAOC;AAKD,wCAcC;AAKD,oCAGC;AA5JD;;GAEG;AACU,QAAA,OAAO,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AACzB,QAAA,MAAM,GAAG,EAAE,GAAG,eAAO,CAAC;AAEnC;;GAEG;AACH,SAAgB,iBAAiB,CAAC,KAAa;IAC7C,OAAO;QACL,UAAU;QACV,SAAS;QACT,UAAU;QACV,SAAS;QACT,UAAU;QACV,UAAU;QACV,SAAS;KACV,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,SAAgB,WAAW,CAAC,KAAc;IACxC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,OAAO,IAAI,KAAK;QAChB,KAAK,IAAI,KAAK;QACd,OAAQ,KAAmB,CAAC,KAAK,KAAK,QAAQ;QAC9C,OAAQ,KAAmB,CAAC,GAAG,KAAK,QAAQ,CAC7C,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAAC,KAAsB,EAAE,GAAU;IACjE,MAAM,SAAS,GAAG,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;IAEpC,2CAA2C;IAC3C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,sBAAsB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IACvD,CAAC;IAED,yCAAyC;IACzC,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,0BAA0B;IAC1B,OAAO,sBAAsB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;AAClD,CAAC;AAED;;GAEG;AACH,SAAgB,sBAAsB,CAAC,MAAuB,EAAE,GAAS;IACvE,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;IAEhC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,UAAU;YACb,OAAO;gBACL,KAAK,EAAE,IAAI,IAAI,CAAC,SAAS,GAAG,cAAM,CAAC,CAAC,WAAW,EAAE;gBACjD,GAAG,EAAE,GAAG,CAAC,WAAW,EAAE;aACvB,CAAC;QACJ,KAAK,SAAS;YACZ,OAAO;gBACL,KAAK,EAAE,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC,GAAG,cAAM,CAAC,CAAC,WAAW,EAAE;gBACrD,GAAG,EAAE,GAAG,CAAC,WAAW,EAAE;aACvB,CAAC;QACJ,KAAK,UAAU;YACb,OAAO;gBACL,KAAK,EAAE,IAAI,IAAI,CAAC,SAAS,GAAG,EAAE,GAAG,cAAM,CAAC,CAAC,WAAW,EAAE;gBACtD,GAAG,EAAE,GAAG,CAAC,WAAW,EAAE;aACvB,CAAC;QACJ,KAAK,SAAS;YACZ,OAAO;gBACL,KAAK,EAAE,GAAG,CAAC,WAAW,EAAE;gBACxB,GAAG,EAAE,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC,GAAG,eAAO,CAAC,CAAC,WAAW,EAAE;aACrD,CAAC;QACJ,KAAK,UAAU;YACb,OAAO;gBACL,KAAK,EAAE,GAAG,CAAC,WAAW,EAAE;gBACxB,GAAG,EAAE,IAAI,IAAI,CAAC,SAAS,GAAG,EAAE,GAAG,eAAO,CAAC,CAAC,WAAW,EAAE;aACtD,CAAC;QACJ,KAAK,UAAU;YACb,OAAO;gBACL,KAAK,EAAE,GAAG,CAAC,WAAW,EAAE;gBACxB,GAAG,EAAE,IAAI,IAAI,CAAC,SAAS,GAAG,cAAM,CAAC,CAAC,WAAW,EAAE;aAChD,CAAC;QACJ,KAAK,SAAS;YACZ,OAAO;gBACL,KAAK,EAAE,GAAG,CAAC,WAAW,EAAE;gBACxB,GAAG,EAAE,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC,GAAG,cAAM,CAAC,CAAC,WAAW,EAAE;aACpD,CAAC;IACN,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,aAAa,CAAC,IAAmB,EAAE,KAAgB;IACjE,MAAM,SAAS,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IACvF,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;IAC9C,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAE1C,OAAO,SAAS,IAAI,KAAK,IAAI,SAAS,IAAI,GAAG,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,MAAiB,EAAE,MAAiB;IAClE,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;IAChD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5C,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;IAChD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAE5C,OAAO,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,CAAC;AAC1C,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc,CAAC,EAAU;IACvC,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;QACd,OAAO,GAAG,EAAE,IAAI,CAAC;IACnB,CAAC;IACD,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC;QAChB,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IACtC,CAAC;IACD,IAAI,EAAE,GAAG,eAAO,EAAE,CAAC;QACjB,OAAO,GAAG,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IACxC,CAAC;IACD,IAAI,EAAE,GAAG,cAAM,EAAE,CAAC;QAChB,OAAO,GAAG,CAAC,EAAE,GAAG,eAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IACzC,CAAC;IACD,OAAO,GAAG,CAAC,EAAE,GAAG,cAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,SAAgB,YAAY,CAAC,UAAkB;IAC7C,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;IAClC,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toCSV = exports.parseCSV = exports.generateCacheKey = exports.DynamoDBCacheProvider = exports.VercelKVCacheProvider = exports.InMemoryCacheProvider = exports.TimeoutError = exports.sleep = exports.withTimeout = exports.withRetry = exports.parseISODate = exports.formatDuration = exports.doRangesOverlap = exports.isDateInRange = exports.resolveTimeRangePreset = exports.resolveTimeRange = exports.isTimeRange = exports.isTimeRangePreset = exports.DAY_MS = exports.HOUR_MS = void 0;
|
|
4
|
+
var date_1 = require("./date");
|
|
5
|
+
Object.defineProperty(exports, "HOUR_MS", { enumerable: true, get: function () { return date_1.HOUR_MS; } });
|
|
6
|
+
Object.defineProperty(exports, "DAY_MS", { enumerable: true, get: function () { return date_1.DAY_MS; } });
|
|
7
|
+
Object.defineProperty(exports, "isTimeRangePreset", { enumerable: true, get: function () { return date_1.isTimeRangePreset; } });
|
|
8
|
+
Object.defineProperty(exports, "isTimeRange", { enumerable: true, get: function () { return date_1.isTimeRange; } });
|
|
9
|
+
Object.defineProperty(exports, "resolveTimeRange", { enumerable: true, get: function () { return date_1.resolveTimeRange; } });
|
|
10
|
+
Object.defineProperty(exports, "resolveTimeRangePreset", { enumerable: true, get: function () { return date_1.resolveTimeRangePreset; } });
|
|
11
|
+
Object.defineProperty(exports, "isDateInRange", { enumerable: true, get: function () { return date_1.isDateInRange; } });
|
|
12
|
+
Object.defineProperty(exports, "doRangesOverlap", { enumerable: true, get: function () { return date_1.doRangesOverlap; } });
|
|
13
|
+
Object.defineProperty(exports, "formatDuration", { enumerable: true, get: function () { return date_1.formatDuration; } });
|
|
14
|
+
Object.defineProperty(exports, "parseISODate", { enumerable: true, get: function () { return date_1.parseISODate; } });
|
|
15
|
+
var retry_1 = require("./retry");
|
|
16
|
+
Object.defineProperty(exports, "withRetry", { enumerable: true, get: function () { return retry_1.withRetry; } });
|
|
17
|
+
Object.defineProperty(exports, "withTimeout", { enumerable: true, get: function () { return retry_1.withTimeout; } });
|
|
18
|
+
Object.defineProperty(exports, "sleep", { enumerable: true, get: function () { return retry_1.sleep; } });
|
|
19
|
+
Object.defineProperty(exports, "TimeoutError", { enumerable: true, get: function () { return retry_1.TimeoutError; } });
|
|
20
|
+
var cache_1 = require("./cache");
|
|
21
|
+
Object.defineProperty(exports, "InMemoryCacheProvider", { enumerable: true, get: function () { return cache_1.InMemoryCacheProvider; } });
|
|
22
|
+
Object.defineProperty(exports, "VercelKVCacheProvider", { enumerable: true, get: function () { return cache_1.VercelKVCacheProvider; } });
|
|
23
|
+
Object.defineProperty(exports, "DynamoDBCacheProvider", { enumerable: true, get: function () { return cache_1.DynamoDBCacheProvider; } });
|
|
24
|
+
Object.defineProperty(exports, "generateCacheKey", { enumerable: true, get: function () { return cache_1.generateCacheKey; } });
|
|
25
|
+
var csv_1 = require("./csv");
|
|
26
|
+
Object.defineProperty(exports, "parseCSV", { enumerable: true, get: function () { return csv_1.parseCSV; } });
|
|
27
|
+
Object.defineProperty(exports, "toCSV", { enumerable: true, get: function () { return csv_1.toCSV; } });
|
|
28
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":";;;AAAA,+BAWgB;AAVd,+FAAA,OAAO,OAAA;AACP,8FAAA,MAAM,OAAA;AACN,yGAAA,iBAAiB,OAAA;AACjB,mGAAA,WAAW,OAAA;AACX,wGAAA,gBAAgB,OAAA;AAChB,8GAAA,sBAAsB,OAAA;AACtB,qGAAA,aAAa,OAAA;AACb,uGAAA,eAAe,OAAA;AACf,sGAAA,cAAc,OAAA;AACd,oGAAA,YAAY,OAAA;AAGd,iCAAsE;AAA7D,kGAAA,SAAS,OAAA;AAAE,oGAAA,WAAW,OAAA;AAAE,8FAAA,KAAK,OAAA;AAAE,qGAAA,YAAY,OAAA;AAGpD,iCAKiB;AAJf,8GAAA,qBAAqB,OAAA;AACrB,8GAAA,qBAAqB,OAAA;AACrB,8GAAA,qBAAqB,OAAA;AACrB,yGAAA,gBAAgB,OAAA;AAGlB,6BAAwC;AAA/B,+FAAA,QAAQ,OAAA;AAAE,4FAAA,KAAK,OAAA"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TimeoutError = void 0;
|
|
4
|
+
exports.withRetry = withRetry;
|
|
5
|
+
exports.sleep = sleep;
|
|
6
|
+
exports.withTimeout = withTimeout;
|
|
7
|
+
/**
|
|
8
|
+
* Default retry options.
|
|
9
|
+
*/
|
|
10
|
+
const DEFAULT_OPTIONS = {
|
|
11
|
+
maxAttempts: 3,
|
|
12
|
+
initialDelayMs: 1000,
|
|
13
|
+
maxDelayMs: 10000,
|
|
14
|
+
backoffMultiplier: 2,
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Execute a function with automatic retry on failure.
|
|
18
|
+
*
|
|
19
|
+
* Uses exponential backoff with jitter for retry delays.
|
|
20
|
+
*
|
|
21
|
+
* @param fn - The async function to execute
|
|
22
|
+
* @param options - Retry configuration options
|
|
23
|
+
* @returns The result of the function
|
|
24
|
+
* @throws The last error if all retries fail
|
|
25
|
+
*/
|
|
26
|
+
async function withRetry(fn, options) {
|
|
27
|
+
const config = {
|
|
28
|
+
...DEFAULT_OPTIONS,
|
|
29
|
+
...options,
|
|
30
|
+
};
|
|
31
|
+
let lastError;
|
|
32
|
+
let delay = config.initialDelayMs;
|
|
33
|
+
for (let attempt = 1; attempt <= config.maxAttempts; attempt++) {
|
|
34
|
+
try {
|
|
35
|
+
return await fn();
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
39
|
+
// Check if we should retry
|
|
40
|
+
const shouldRetry = attempt < config.maxAttempts && (config.isRetryable ? config.isRetryable(lastError) : true);
|
|
41
|
+
if (!shouldRetry) {
|
|
42
|
+
throw lastError;
|
|
43
|
+
}
|
|
44
|
+
// Notify about retry
|
|
45
|
+
if (config.onRetry) {
|
|
46
|
+
config.onRetry(lastError, attempt, delay);
|
|
47
|
+
}
|
|
48
|
+
// Wait with jitter
|
|
49
|
+
await sleep(addJitter(delay));
|
|
50
|
+
// Increase delay for next retry
|
|
51
|
+
delay = Math.min(delay * config.backoffMultiplier, config.maxDelayMs);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
throw lastError;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Sleep for a given duration.
|
|
58
|
+
*/
|
|
59
|
+
function sleep(ms) {
|
|
60
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Add random jitter to a delay value (±25%).
|
|
64
|
+
*/
|
|
65
|
+
function addJitter(delay) {
|
|
66
|
+
const jitter = delay * 0.25 * (Math.random() * 2 - 1);
|
|
67
|
+
return Math.max(0, Math.round(delay + jitter));
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Execute a function with a timeout.
|
|
71
|
+
*
|
|
72
|
+
* @param fn - The async function to execute
|
|
73
|
+
* @param timeoutMs - Maximum execution time in milliseconds
|
|
74
|
+
* @param timeoutMessage - Optional error message for timeout
|
|
75
|
+
* @returns The result of the function
|
|
76
|
+
* @throws TimeoutError if the function takes longer than timeoutMs
|
|
77
|
+
*/
|
|
78
|
+
async function withTimeout(fn, timeoutMs, timeoutMessage = 'Operation timed out') {
|
|
79
|
+
let timeoutId;
|
|
80
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
81
|
+
timeoutId = setTimeout(() => {
|
|
82
|
+
reject(new TimeoutError(timeoutMessage, timeoutMs));
|
|
83
|
+
}, timeoutMs);
|
|
84
|
+
});
|
|
85
|
+
try {
|
|
86
|
+
const result = await Promise.race([fn(), timeoutPromise]);
|
|
87
|
+
clearTimeout(timeoutId);
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
clearTimeout(timeoutId);
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Error thrown when an operation times out.
|
|
97
|
+
*/
|
|
98
|
+
class TimeoutError extends Error {
|
|
99
|
+
code = 'TIMEOUT_ERROR';
|
|
100
|
+
timeoutMs;
|
|
101
|
+
constructor(message, timeoutMs) {
|
|
102
|
+
super(message);
|
|
103
|
+
this.name = 'TimeoutError';
|
|
104
|
+
this.timeoutMs = timeoutMs;
|
|
105
|
+
Object.setPrototypeOf(this, TimeoutError.prototype);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
exports.TimeoutError = TimeoutError;
|
|
109
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../../src/utils/retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAG/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { AlertFeed } from '../core';
|
|
2
|
+
import { AlertQueryRequestSchema, transformRequestToQuery } from '../schemas';
|
|
3
|
+
import { ValidationError } from '../errors';
|
|
4
|
+
/**
|
|
5
|
+
* Create an AWS Lambda handler for the AlertFeed.
|
|
6
|
+
*
|
|
7
|
+
* Supports both GET (query parameters) and POST (JSON body) requests.
|
|
8
|
+
*
|
|
9
|
+
* @param options - Handler configuration options
|
|
10
|
+
* @returns Lambda handler function
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { createLambdaHandler } from 'local-risk-alert-feed/adapters/lambda';
|
|
15
|
+
* import { PhoenixPolicePlugin } from 'local-risk-alert-feed/plugins/police-blotter';
|
|
16
|
+
*
|
|
17
|
+
* export const handler = createLambdaHandler({
|
|
18
|
+
* plugins: [{ plugin: new PhoenixPolicePlugin() }]
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export function createLambdaHandler(options) {
|
|
23
|
+
const feed = new AlertFeed(options);
|
|
24
|
+
const corsOrigin = options.corsOrigin ?? '*';
|
|
25
|
+
const corsHeaders = [
|
|
26
|
+
'Content-Type',
|
|
27
|
+
'Authorization',
|
|
28
|
+
...(options.corsHeaders ?? []),
|
|
29
|
+
].join(', ');
|
|
30
|
+
const corsMethods = ['GET', 'POST', 'OPTIONS', ...(options.corsMethods ?? [])].join(', ');
|
|
31
|
+
// Initialize plugins
|
|
32
|
+
if (options.plugins) {
|
|
33
|
+
feed.registerPlugins(options.plugins).catch(console.error);
|
|
34
|
+
}
|
|
35
|
+
return async (event, _context) => {
|
|
36
|
+
// Handle CORS preflight
|
|
37
|
+
if (event.httpMethod === 'OPTIONS') {
|
|
38
|
+
return createCorsResponse(corsOrigin, corsHeaders, corsMethods);
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
// Parse request
|
|
42
|
+
const requestData = parseRequest(event);
|
|
43
|
+
// Validate request
|
|
44
|
+
const parseResult = AlertQueryRequestSchema.safeParse(requestData);
|
|
45
|
+
if (!parseResult.success) {
|
|
46
|
+
return createErrorResponse(400, 'Validation Error', ValidationError.fromZodError(parseResult.error).toJSON(), corsOrigin);
|
|
47
|
+
}
|
|
48
|
+
// Transform to query
|
|
49
|
+
const query = transformRequestToQuery(parseResult.data);
|
|
50
|
+
// Execute query
|
|
51
|
+
const response = await feed.query(query);
|
|
52
|
+
return createSuccessResponse(response, corsOrigin);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
console.error('AlertFeed error:', error);
|
|
56
|
+
if (error instanceof ValidationError) {
|
|
57
|
+
return createErrorResponse(400, 'Validation Error', error.toJSON(), corsOrigin);
|
|
58
|
+
}
|
|
59
|
+
return createErrorResponse(500, 'Internal Server Error', {
|
|
60
|
+
message: error instanceof Error ? error.message : 'An unexpected error occurred',
|
|
61
|
+
}, corsOrigin);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Parse request data from Lambda event.
|
|
67
|
+
*/
|
|
68
|
+
function parseRequest(event) {
|
|
69
|
+
if (event.httpMethod === 'POST' && event.body) {
|
|
70
|
+
try {
|
|
71
|
+
return JSON.parse(event.body);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
throw new 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 = event.queryStringParameters ?? {};
|
|
81
|
+
const multiParams = event.multiValueQueryStringParameters ?? {};
|
|
82
|
+
return {
|
|
83
|
+
latitude: params.latitude ? parseFloat(params.latitude) : undefined,
|
|
84
|
+
longitude: params.longitude ? parseFloat(params.longitude) : undefined,
|
|
85
|
+
radiusMeters: params.radiusMeters ? parseFloat(params.radiusMeters) : undefined,
|
|
86
|
+
limit: params.limit ? parseInt(params.limit, 10) : undefined,
|
|
87
|
+
minRiskLevel: params.minRiskLevel,
|
|
88
|
+
timeRange: params.timeRange,
|
|
89
|
+
categories: multiParams.categories ?? (params.categories ? [params.categories] : undefined),
|
|
90
|
+
temporalTypes: multiParams.temporalTypes ?? (params.temporalTypes ? [params.temporalTypes] : undefined),
|
|
91
|
+
includePluginResults: params.includePluginResults === 'true',
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Create a success response.
|
|
96
|
+
*/
|
|
97
|
+
function createSuccessResponse(data, corsOrigin) {
|
|
98
|
+
return {
|
|
99
|
+
statusCode: 200,
|
|
100
|
+
headers: getCorsHeaders(corsOrigin),
|
|
101
|
+
body: JSON.stringify(data),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Create an error response.
|
|
106
|
+
*/
|
|
107
|
+
function createErrorResponse(statusCode, error, details, corsOrigin) {
|
|
108
|
+
return {
|
|
109
|
+
statusCode,
|
|
110
|
+
headers: getCorsHeaders(corsOrigin),
|
|
111
|
+
body: JSON.stringify({ error, ...details }),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Create a CORS preflight response.
|
|
116
|
+
*/
|
|
117
|
+
function createCorsResponse(corsOrigin, corsHeaders, corsMethods) {
|
|
118
|
+
const origin = Array.isArray(corsOrigin) ? corsOrigin[0] : corsOrigin;
|
|
119
|
+
return {
|
|
120
|
+
statusCode: 204,
|
|
121
|
+
headers: {
|
|
122
|
+
'Access-Control-Allow-Origin': origin,
|
|
123
|
+
'Access-Control-Allow-Headers': corsHeaders,
|
|
124
|
+
'Access-Control-Allow-Methods': corsMethods,
|
|
125
|
+
'Access-Control-Max-Age': '86400',
|
|
126
|
+
},
|
|
127
|
+
body: '',
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Get CORS headers for response.
|
|
132
|
+
*/
|
|
133
|
+
function getCorsHeaders(corsOrigin) {
|
|
134
|
+
const origin = Array.isArray(corsOrigin) ? corsOrigin[0] : corsOrigin;
|
|
135
|
+
return {
|
|
136
|
+
'Content-Type': 'application/json',
|
|
137
|
+
'Access-Control-Allow-Origin': origin,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
//# 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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"}
|