uddf2js
v1.0.0
Published
Convert UDDF to an easy to use JS format and handle unit conversions
Maintainers
Readme
uddf2js
Parse UDDF XML dive logs to JavaScript objects with optional unit conversion.
Features
- Parses UDDF (Universal Dive Data Format) XML files
- Returns raw SI values by default, with optional metric/imperial conversion
- Always returns arrays for
repetitiongroup,dive, andsamples.waypoint - Validates inputs and throws explicit errors for invalid XML/unit inputs
- Robust against missing sections
Installation
npm install uddf2jsUsage (conversion optional)
const { parseUDDF } = require('uddf2js');
const fs = require('fs');
const xmlData = fs.readFileSync('mydive.uddf', 'utf8');
// Convert to metric
parseUDDF(xmlData, 'metric').then(result => {
console.log(result.unit); // 'metric'
const waypoint = result.data.uddf.profiledata.repetitiongroup[0].dive[0].samples.waypoint[0];
console.log(waypoint.depth); // meters
});
// No conversion: raw SI as stored in UDDF
parseUDDF(xmlData).then(result => {
console.log(result.unit); // 'si'
const waypoint = result.data.uddf.profiledata.repetitiongroup[0].dive[0].samples.waypoint[0];
console.log(waypoint.depth); // often string from XML, e.g. '10'
});Waypoint Array Guarantee
samples.waypoint is always an array, even when only one waypoint exists in the XML.
const singleWaypointXml = `<?xml version="1.0" encoding="utf-8"?>
<uddf>
<profiledata>
<repetitiongroup>
<dive>
<samples>
<waypoint><depth>10</depth></waypoint>
</samples>
</dive>
</repetitiongroup>
</profiledata>
</uddf>`;
const result = await parseUDDF(singleWaypointXml);
console.log(Array.isArray(result.data.uddf.profiledata.repetitiongroup[0].dive[0].samples.waypoint)); // trueUnit Options (when conversion is requested)
'si'(default): raw SI values from UDDF (no conversion pass)'metric': Celsius, liters, meters, bar- seconds are not converted to minutes
'imperial': Fahrenheit, cubic feet, feet, PSI- seconds are converted to minutes, but if it's between 1 and 59 seconds, it will be a string like
'0:ss'
- seconds are converted to minutes, but if it's between 1 and 59 seconds, it will be a string like
API
parseUDDF(xmlData, unit)
xmlData: String containing UDDF XMLunit:'si' | 'metric' | 'imperial'(optional)- omit or pass
'si': no conversion pass - pass
'metric'or'imperial': convert supported numeric fields
- omit or pass
- Returns: Promise resolving to
{ unit, data }
Errors
- Throws
TypeErrorwhenxmlDatais missing/empty. - Throws
RangeErrorwhenunitis not one of'si' | 'metric' | 'imperial'. - Throws
Errorprefixed withFailed to parse UDDF XML:for parse failures.
Quality Gates
npm run lint: ESLint static checks (0 warnings allowed)npm run typecheck: strict TypeScript checksnpm test: unit/integration testsnpm run security: production dependency vulnerability checknpm run verify:version: requires apackage.jsonversion bump when publish-impacting files change (CI PR gate)- Git pre-commit hook: runs
lint-staged,typecheck, and tests before commits
License
MIT
