UNPKG

signalk-parquet

Version:

Vessel data Parquet file archive with automated value and geospatial triggers. History API compliant with cloud backups and queries.

100 lines 3.47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.InvalidResolutionError = void 0; exports.parseDurationToMillis = parseDurationToMillis; exports.parseResolutionToMillis = parseResolutionToMillis; const core_1 = require("@js-joda/core"); /** * Parse duration in multiple formats, return milliseconds. * * Formats (detection order): * 1. ISO 8601: PT1H, PT30M, P1D, PT1H30M * 2. Integer seconds: 3600, 60 * 3. Shorthand: 1h, 30m, 5s, 2d (backward compatible) */ function parseDurationToMillis(duration) { const trimmed = duration.trim(); // ISO 8601 (starts with P) if (trimmed.toUpperCase().startsWith('P')) { return core_1.Duration.parse(trimmed).toMillis(); } // Integer seconds (pure digits) if (/^\d+$/.test(trimmed)) { return parseInt(trimmed, 10) * 1000; } // Shorthand (1h, 30m, 5s, 2d) const match = trimmed.match(/^(\d+)([smhd])$/i); if (match) { const value = parseInt(match[1]); const unit = match[2].toLowerCase(); switch (unit) { case 's': return value * 1000; case 'm': return value * 60 * 1000; case 'h': return value * 60 * 60 * 1000; case 'd': return value * 24 * 60 * 60 * 1000; } } throw new Error(`Invalid duration: ${duration}. Use PT1H, 3600, or 1h`); } class InvalidResolutionError extends Error { constructor(message) { super(message); this.name = 'InvalidResolutionError'; } } exports.InvalidResolutionError = InvalidResolutionError; const RESOLUTION_UNIT_MILLIS = { s: 1000, m: 60000, h: 3600000, d: 86400000, }; const RESOLUTION_TIME_EXPRESSION = /^(\d+)([smhd])$/i; /** * Parse the History API `resolution` query parameter into milliseconds. * * Per the SignalK History API spec, resolution is a number of seconds or a * time expression of the form `<integer><unit>` where unit is s|m|h|d. */ function parseResolutionToMillis(resolution) { const reject = () => { throw new InvalidResolutionError(`resolution parameter must be a positive number of seconds or a time expression like '1s', '1m', '1h', '1d'`); }; const toMillisOrReject = (seconds) => { const millis = seconds * 1000; if (!Number.isFinite(millis) || millis <= 0) reject(); return millis; }; if (typeof resolution === 'number') { if (!Number.isFinite(resolution) || resolution <= 0) reject(); return toMillisOrReject(resolution); } // Express can hand us an array (?resolution=1s&resolution=2s) typed as // string by the route layer's cast; reject anything that isn't actually // a string before calling .trim(). if (typeof resolution !== 'string') reject(); const trimmed = resolution.trim(); const match = RESOLUTION_TIME_EXPRESSION.exec(trimmed); if (match) { const value = Number(match[1]); if (value <= 0) reject(); const millis = value * RESOLUTION_UNIT_MILLIS[match[2].toLowerCase()]; if (!Number.isFinite(millis) || millis <= 0) reject(); return millis; } const asNumber = Number(trimmed); if (trimmed !== '' && Number.isFinite(asNumber) && asNumber > 0) { return toMillisOrReject(asNumber); } return reject(); } //# sourceMappingURL=duration-parser.js.map