Skip to content

Francescodib/coordinate-sanitizer

Repository files navigation

Coordinate Sanitizer

npm version npm downloads License: MIT Node.js Support

coordinate-sanitizer

A flexible and robust JavaScript library for parsing and sanitizing astronomical coordinates. Handles various coordinate formats and converts them to standardized formats suitable for astronomical applications.

Installation

npm install coordinate-sanitizer

NPM

Features

  • Multiple Input Formats: Supports HMS/DMS, decimal, and compact coordinate formats
  • Flexible Output: Configurable output formats (Aladin, decimal, HMS/DMS)
  • Range Validation: Optional validation of RA (0-24h) and DEC (-90°/+90°) ranges
  • Security: Built-in protection against malicious input
  • Object Recognition: Automatically detects and passes through astronomical object names
  • Unicode Support: Handles various Unicode symbols and separators
  • High Performance: Optimized for batch processing
  • Zero Dependencies: Lightweight with no external dependencies
  • Universal: Works in Node.js and browsers
  • TypeScript Support: Includes complete TypeScript definitions

Quick Start

const CoordinateSanitizer = require('coordinate-sanitizer');

const sanitizer = new CoordinateSanitizer();

// Parse various coordinate formats
const result1 = sanitizer.sanitizeCoordinates('12h 34m 56s, +12° 34\' 56"');
console.log(result1.coordinates); // "12 34 56.000, +12 34 56.000"

const result2 = sanitizer.sanitizeCoordinates('M31');
console.log(result2.coordinates); // "M31" (passed through as object name)

const result3 = sanitizer.sanitizeCoordinates('123.456, -12.345');
console.log(result3.coordinates); // "08 13 49.440, -12 20 42.000"

Package Information

Property Value
Package Name coordinate-sanitizer
Version npm version
Weekly Downloads npm downloads
Bundle Size npm bundle size
License License
Node.js Support Node.js

Supported Input Formats

Coordinate Formats

  • HMS/DMS: 12h 34m 56.78s, +12° 34' 56.78"
  • Colon separated: 12:34:56.78, +12:34:56.78
  • Decimal: 123.456, -12.345
  • Compact: 123456, -123456
  • Space separated: 12 34 56.7 -45 12 34.5
  • Mixed formats: 12h 34m 56s, +12:34:56

Object Names

  • Messier objects: M31, M42
  • NGC objects: NGC 1234, NGC 7000
  • IC objects: IC 1396
  • Other catalogs: HD 209458, HIP 27989, SAO 123456
  • Named stars: Polaris, Vega, 51 Eri

Separators

Supports multiple separators between RA and DEC:

  • Comma: ,
  • Semicolon: ;
  • Middle dot: ·
  • Bullet:

API Reference

Constructor

const sanitizer = new CoordinateSanitizer(options);

Options:

  • outputFormat (string): Output format - 'aladin', 'decimal', 'hms-dms' (default: 'aladin')
  • precision (number): Decimal precision for output (default: 6)
  • validateRanges (boolean): Enable range validation (default: true)
  • strictMode (boolean): Enable strict parsing mode (default: false). In strict mode, compact 6-digit formats and space-separated coordinates without an explicit separator are rejected; only unambiguous formats are accepted (HMS/DMS with markers, colon-separated, decimal).

Methods

sanitizeCoordinates(input)

Main method for sanitizing coordinates.

Parameters:

  • input (string): Input coordinate string

Returns:

{
  isValid: boolean,      // Whether the input was successfully parsed
  coordinates: string,   // Sanitized coordinate string
  error: string|null,    // Error message if parsing failed
  metadata: {            // Additional information about the parsing
    inputFormat: string, // 'coordinates', 'object-name', 'already-valid'
    outputFormat: string,// Output format used
    ra: object,          // RA parsing details (if coordinates)
    dec: object          // DEC parsing details (if coordinates)
  }
}

Static Methods

getSupportedFormats()

Returns information about supported input and output formats.

createPreset(preset)

Creates a sanitizer with predefined configurations:

  • 'aladin': Aladin format with range validation
  • 'decimal': Decimal format with high precision
  • 'loose': Aladin format without range validation
  • 'strict': Aladin format with strict parsing and validation

Throws an Error if an unknown preset name is provided.

Usage Examples

Different Output Formats

// Aladin format (default)
const aladinSanitizer = new CoordinateSanitizer({ outputFormat: 'aladin' });
const result1 = aladinSanitizer.sanitizeCoordinates('12h 34m 56s, +12° 34\' 56"');
console.log(result1.coordinates); // "12 34 56.000, +12 34 56.000"

// Decimal format
const decimalSanitizer = new CoordinateSanitizer({ outputFormat: 'decimal' });
const result2 = decimalSanitizer.sanitizeCoordinates('12h 34m 56s, +12° 34\' 56"');
console.log(result2.coordinates); // "12.582222, 12.582222"

// HMS/DMS format
const hmsSanitizer = new CoordinateSanitizer({ outputFormat: 'hms-dms' });
const result3 = hmsSanitizer.sanitizeCoordinates('12.5, 12.5');
console.log(result3.coordinates); // "12h 30m 00.000s, +12° 30' 00.000""

Using Presets

// Quick setup with presets
const aladinSanitizer  = CoordinateSanitizer.createPreset('aladin');
const decimalSanitizer = CoordinateSanitizer.createPreset('decimal');
const looseSanitizer   = CoordinateSanitizer.createPreset('loose');
const strictSanitizer  = CoordinateSanitizer.createPreset('strict');

const result = aladinSanitizer.sanitizeCoordinates('12h 34m 56s, +12° 34\' 56"');

// createPreset throws for unknown names
try {
  CoordinateSanitizer.createPreset('unknown');
} catch (e) {
  console.error(e.message); // "Unknown preset: "unknown". Available presets: aladin, decimal, loose, strict"
}

Strict Mode

Strict mode accepts only unambiguous coordinate formats and requires an explicit separator between RA and DEC:

const strict = new CoordinateSanitizer({ strictMode: true });

// Accepted: HMS/DMS with markers, colon-separated, decimal
strict.sanitizeCoordinates('12h 34m 56s, +12° 34\' 56"').isValid; // true
strict.sanitizeCoordinates('12:34:56, +12:34:56').isValid;         // true
strict.sanitizeCoordinates('12.5, -45.75').isValid;                // true

// Rejected: compact format, space-separated without explicit separator
strict.sanitizeCoordinates('123456, -123456').isValid;       // false
strict.sanitizeCoordinates('12 34 56 -45 12 34').isValid;    // false

Range Validation

const sanitizer = new CoordinateSanitizer({ validateRanges: true });

// Valid coordinates
const valid = sanitizer.sanitizeCoordinates('12h 00m 00s, +45° 00\' 00"');
console.log(valid.isValid); // true

// Invalid RA (> 24h)
const invalid = sanitizer.sanitizeCoordinates('25h 00m 00s, +45° 00\' 00"');
console.log(invalid.isValid); // false
console.log(invalid.error); // "RA out of range: 25 (must be 0-24 hours)"

Batch Processing

const sanitizer = new CoordinateSanitizer();

const inputs = [
  'M31',
  'NGC 1234',
  '12h 34m 56s, +12° 34\' 56"',
  '13:45:12.34, -23:45:12.34'
];

const results = inputs.map(input => {
  const result = sanitizer.sanitizeCoordinates(input);
  return {
    input,
    valid: result.isValid,
    output: result.coordinates,
    type: result.metadata?.inputFormat
  };
});

console.table(results);

Integration with Telescope Control

class TelescopeController {
  constructor() {
    this.sanitizer = new CoordinateSanitizer({
      outputFormat: 'aladin',
      validateRanges: true
    });
  }

  gotoTarget(target) {
    const result = this.sanitizer.sanitizeCoordinates(target);
    
    if (!result.isValid) {
      throw new Error(`Invalid target: ${result.error}`);
    }

    // Send to telescope
    this.sendToTelescope(result.coordinates);
    
    return {
      target: result.coordinates,
      inputType: result.metadata.inputFormat
    };
  }
}

Error Handling

const sanitizer = new CoordinateSanitizer();

function safeSearch(input) {
  try {
    const result = sanitizer.sanitizeCoordinates(input);
    
    if (!result.isValid) {
      return {
        success: false,
        error: result.error,
        suggestion: 'Please check coordinate format'
      };
    }

    return {
      success: true,
      coordinates: result.coordinates,
      inputType: result.metadata.inputFormat
    };
  } catch (error) {
    return {
      success: false,
      error: error.message,
      suggestion: 'Please contact support'
    };
  }
}

Browser Usage

Script Tag

<script src="path/to/coordinate-sanitizer.js"></script>
<script>
  const sanitizer = new CoordinateSanitizer();
  const result = sanitizer.sanitizeCoordinates('M31');
  console.log(result.coordinates);
</script>

ES6 Modules (bundlers)

When using a bundler such as webpack or Rollup, the module field is resolved automatically:

import CoordinateSanitizer from 'coordinate-sanitizer';

const sanitizer = new CoordinateSanitizer();
const result = sanitizer.sanitizeCoordinates('12h 34m 56s, +12° 34\' 56"');

Node.js native ESM: the package uses CommonJS (require). In a .mjs file or "type": "module" project use createRequire or a dynamic import() of the CJS entry point.

TypeScript Support

The library includes complete TypeScript definitions:

import CoordinateSanitizer, { 
  CoordinateSanitizerOptions, 
  SanitizationResult 
} from 'coordinate-sanitizer';

const options: CoordinateSanitizerOptions = {
  outputFormat: 'decimal',
  precision: 4,
  validateRanges: true
};

const sanitizer = new CoordinateSanitizer(options);
const result: SanitizationResult = sanitizer.sanitizeCoordinates('M31');

Performance

The library is optimized for high-performance applications:

  • 10,000+ coordinates/second on modern hardware
  • Zero dependencies - no external libraries
  • Efficient regex patterns for fast parsing
  • Minimal memory footprint
  • Batch processing support

Security

The library includes built-in security features:

  • Input sanitization prevents script injection
  • Malicious content detection blocks dangerous patterns
  • Safe parsing with input validation
  • No eval() or dynamic code execution

Error Handling

The library provides detailed error messages for debugging:

const result = sanitizer.sanitizeCoordinates('invalid input');
if (!result.isValid) {
  console.log(`Error: ${result.error}`);
  // Handle error appropriately
}

Common error types:

  • Invalid coordinate format
  • Out of range values (RA > 24h, DEC > ±90°)
  • Malformed input strings
  • Security violations

Testing

# Unit tests (52 tests)
npm test

# Integration tests – round-trip, cross-format consistency, known objects (29 tests)
npm run test:integration

# Full suite
npm run test:all

# Run examples
npm run example

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Setup

# Clone the repository
git clone https://github.com/Francescodib/coordinate-sanitizer.git
cd coordinate-sanitizer

# Install dependencies
npm install

# Run unit tests
npm test

# Run integration tests
npm run test:integration

# Run full suite
npm run test:all

# Run examples
npm run example

Stats

  • Lines of code: ~850
  • Unit tests: 52
  • Integration tests: 29 (round-trip, cross-format, known objects)
  • Performance: 10,000+ coordinates/second
  • Bundle size: Minimal (zero dependencies)
  • Formats supported: 15+ input variations

Changelog

1.0.4

  • Implemented strictMode option (was documented but had no effect)
  • Fixed floating point carry overflow in decimalToHMS / decimalToDMS and in formatting functions
  • Fixed isValidFormat to detect already-valid input for all output formats, not only aladin
  • Fixed formatHMSDMS zero-padding for hours, minutes, and degree components
  • createPreset now throws a descriptive Error for unknown preset names
  • Updated TypeScript definitions: added strictMode, createPreset signature, fixed exports
  • Added 29 integration tests (round-trip idempotency, cross-format consistency, known objects)

See CHANGELOG.md for the full history.

License

MIT License - see LICENSE file for details.

Related Projects

Links

Support

Author

Francesco di Biase

About

npm library for parsing and sanitizing astronomical coordinates (RA/DEC)

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors