const swisseph = require('swisseph')
const path = require('path')
// Point to ephemeris data files
swisseph.swe_set_ephe_path(
path.join(process.cwd(), 'node_modules/swisseph/ephe')
)
// Convert birth date/time to Julian Day Number
function toJulianDay(year, month, day, hourDecimal) {
return swisseph.swe_julday(year, month, day, hourDecimal, swisseph.SE_GREG_CAL)
}
// Get sidereal (Vedic) planet position with Lahiri ayanamsa
function getPlanetSidereal(jd, planetId) {
// Set Lahiri ayanamsa (most common in Vedic astrology)
swisseph.swe_set_sid_mode(swisseph.SE_SIDM_LAHIRI, 0, 0)
const flags = swisseph.SEFLG_SWIEPH | swisseph.SEFLG_SIDEREAL
const result = swisseph.swe_calc_ut(jd, planetId, flags)
if (result.flag === swisseph.ERR) {
throw new Error(`Ephemeris error for planet ${planetId}`)
}
return {
longitude: result.longitude, // 0-360 degrees
latitude: result.latitude,
speed: result.longitudeSpeed,
retrograde: result.longitudeSpeed < 0,
}
}
// Example: Get Sun and Moon for Mumbai birth chart
const jd = toJulianDay(1990, 6, 15, 8.5) // 15 Jun 1990, 08:30 IST
const sun = getPlanetSidereal(jd, swisseph.SE_SUN)
const moon = getPlanetSidereal(jd, swisseph.SE_MOON)
const mars = getPlanetSidereal(jd, swisseph.SE_MARS)
console.log('Sun longitude:', sun.longitude.toFixed(4)) // e.g. 60.3421 (Taurus)
console.log('Moon retrograde:', moon.retrograde) // false
console.log('Mars retrograde:', mars.retrograde) // true/false// Convert longitude to nakshatra, pada, and sign
const NAKSHATRAS = [
'Ashwini','Bharani','Krittika','Rohini','Mrigashira','Ardra',
'Punarvasu','Pushya','Ashlesha','Magha','Purva Phalguni','Uttara Phalguni',
'Hasta','Chitra','Swati','Vishakha','Anuradha','Jyeshtha',
'Mula','Purva Ashadha','Uttara Ashadha','Shravana','Dhanishtha','Shatabhisha',
'Purva Bhadrapada','Uttara Bhadrapada','Revati'
]
const SIGNS = [
'Aries','Taurus','Gemini','Cancer','Leo','Virgo',
'Libra','Scorpio','Sagittarius','Capricorn','Aquarius','Pisces'
]
function parsePosition(longitude) {
const nakshatraIndex = Math.floor(longitude / (360 / 27))
const pada = Math.floor((longitude % (360 / 27)) / (360 / 108)) + 1
const signIndex = Math.floor(longitude / 30)
const degreeInSign = longitude % 30
return {
nakshatra: NAKSHATRAS[nakshatraIndex],
pada,
sign: SIGNS[signIndex],
degree: degreeInSign.toFixed(2),
fullDegree: longitude.toFixed(4),
}
}
// Example usage
const sunPos = parsePosition(sun.longitude)
console.log(sunPos)
// { nakshatra: 'Mrigashira', pada: 4, sign: 'Taurus', degree: '0.34' }// Compute ascendant (lagna) — requires birth location
function getAscendant(jd, latitude, longitude, ayanamsa = swisseph.SE_SIDM_LAHIRI) {
swisseph.swe_set_sid_mode(ayanamsa, 0, 0)
// swe_houses returns house cusps and ASC/MC
const houses = swisseph.swe_houses(jd, latitude, longitude, 'P') // 'P' = Placidus
// Subtract ayanamsa for sidereal ascendant
const ayanamsaValue = swisseph.swe_get_ayanamsa_ut(jd)
let siderealAsc = houses.ascendant - ayanamsaValue
if (siderealAsc < 0) siderealAsc += 360
if (siderealAsc >= 360) siderealAsc -= 360
return parsePosition(siderealAsc)
}
// Mumbai: lat 19.0760, lon 72.8777
const ascendant = getAscendant(jd, 19.0760, 72.8777)
console.log('Ascendant:', ascendant.sign, ascendant.degree + '°')