├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .flowconfig ├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE ├── README.md ├── lib ├── apod.js ├── cad.js ├── config.js ├── earth.js ├── eonet.js ├── epic.js ├── fireballs.js ├── images.js ├── index.js ├── mars-photos.js ├── neo.js ├── nhats.js ├── patents.js ├── scout.js ├── sentry.js ├── sounds.js └── util.js ├── package-lock.json ├── package.json ├── src ├── apod.js ├── cad.js ├── config.js ├── earth.js ├── eonet.js ├── epic.js ├── fireballs.js ├── images.js ├── index.js ├── mars-photos.js ├── neo.js ├── nhats.js ├── patents.js ├── scout.js ├── sentry.js ├── sounds.js └── util.js └── tests ├── .eslintrc.json ├── apod.spec.js ├── cad.spec.js ├── config.spec.js ├── earth.spec.js ├── eonet.spec.js ├── epic.spec.js ├── fireballs.spec.js ├── helper.js ├── images.spec.js ├── mars-photos.spec.js ├── neo.spec.js ├── nhats.spec.js ├── patents.spec.js ├── scout.spec.js ├── sentry.spec.js └── sounds.spec.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "es2015", 4 | "stage-2" 5 | ], 6 | "plugins": [ 7 | "transform-flow-strip-types", 8 | "add-module-exports", 9 | "transform-runtime" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | 11 | # Matches multiple files with brace expansion notation 12 | # Set default charset 13 | [*.{js,json,md}] 14 | charset = utf-8 15 | 16 | # 2 space indentation 17 | [*.js] 18 | indent_style = space 19 | indent_size = 2 20 | 21 | # Matches the exact files either package.json or .travis.yml 22 | [{package.json,.travis.yml,.eslintrc.json}] 23 | indent_style = space 24 | indent_size = 2 25 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | lib 2 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": "airbnb/base", 4 | "parser": "babel-eslint", 5 | "plugins": [ 6 | "flow-vars", 7 | "flowtype" 8 | ], 9 | "env": { 10 | "es6": true, 11 | "node": true, 12 | "mocha": true 13 | }, 14 | "globals": { 15 | "expect": false, 16 | "assert": false 17 | }, 18 | "rules": { 19 | "quotes": [2, "single"], 20 | "curly": 2, 21 | "semi": [2, "always"], 22 | "flow-vars/define-flow-type": 2, 23 | "flow-vars/use-flow-type": 2, 24 | "flowtype/require-parameter-type": 2, 25 | "flowtype/require-return-type": [ 26 | 2, 27 | "always", 28 | { "annotateUndefined": "always" } 29 | ], 30 | "flowtype/space-after-type-colon": [ 31 | 2, 32 | "always" 33 | ], 34 | "flowtype/space-before-type-colon": [ 35 | 2, 36 | "never" 37 | ], 38 | "flowtype/type-id-match": [ 39 | 2, 40 | "^([A-Z][a-z0-9]+)+Type$" 41 | ] 42 | }, 43 | "settings": { 44 | "flowtype": { 45 | "onlyFilesWithFlowAnnotation": false 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | .*/node_modules/.* 3 | .*/lib/.* 4 | .*/tests/.* 5 | 6 | [options] 7 | module.ignore_non_literal_requires=true 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | logs 2 | *.log 3 | npm-debug.log* 4 | pids 5 | *.pid 6 | *.seed 7 | node_modules 8 | .DS_Store 9 | .idea -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | tests 3 | .DS_Store 4 | logs 5 | *.log 6 | npm-debug.log* 7 | pids 8 | *.pid 9 | *.seed 10 | node_modules 11 | .editorconfig 12 | .eslintignore 13 | .eslintrc.json 14 | .flowconfig 15 | .gitignore 16 | .babelrc 17 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "node" 4 | script: 5 | - npm run build 6 | - npm run test 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016~present AJ Funk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## NASA SDK 2 | NASA API wrapper for Node.js 3 | 4 | [![Build Status](https://travis-ci.org/AJFunk/nasa-sdk.svg?branch=master)](https://travis-ci.org/AJFunk/nasa-sdk) 5 | 6 | This SDK makes it simple to integrate many of NASA's APIs. Some of them require getting an API key from [https://api.nasa.gov](https://api.nasa.gov), which is free and easy. API keys are limited to 1000 requests/hour. We have implemented error checking in order to prevent bad requests being sent to NASA APIs, thus saving you from wasting your requests. 7 | 8 | This project uses modern ES2016+ syntax, which means you can use promises (as shown in the documentation) or async/await. 9 | 10 | Our goal is to integrate as many APIs as possible to allow JavaScript developers to easily access information about our planet, solar system, and beyond. If you have any APIs you would like to see added, please let us know by opening an issue! 11 | 12 | ### Installation 13 | ```sh 14 | npm install --save nasa-sdk 15 | ``` 16 | ### Usage 17 | ```javascript 18 | import { 19 | APOD, 20 | CAD, 21 | Earth, 22 | EONET, 23 | EPIC, 24 | Fireballs, 25 | Images, 26 | MarsPhotos, 27 | NEO, 28 | NHATS, 29 | Patents, 30 | Scout, 31 | Sentry, 32 | Sounds, 33 | } from 'nasa-sdk'; 34 | ``` 35 | Only import the modules you need. For example, if you only need the `APOD` and `EONET` modules: 36 | ```javascript 37 | import { 38 | APOD, 39 | EONET, 40 | } from 'nasa-sdk'; 41 | ``` 42 | To set your API Key, set the environment variable `NASA_API_KEY`. Alternatively, you can set the configuration manually: 43 | ```javascript 44 | import { setNasaApiKey } from 'nasa-sdk'; 45 | setNasaApiKey('') 46 | ``` 47 | 48 | Be sure to reference [NASA's API docs](https://api.nasa.gov/api.html) 49 | 50 | ## APOD - Astronomy Picture of the Day 51 | * [APOD.fetch()](#apod-fetch) 52 | 53 | ## CAD - SBDB (Small-Body DataBase) Close-Approach Data 54 | * [CAD.fetch()](#cad-fetch) 55 | 56 | ## Earth - Landsat 8 Imagery of Earth 57 | * [Earth.imagery()](#earth-imagery) 58 | * [Earth.assets()](#earth-assets) 59 | 60 | ## EONET - Earth Observatory Natural Event Tracker 61 | * [EONET.events()](#eonet-events) 62 | * [EONET.categories()](#eonet-categories) 63 | * [EONET.sources()](#eonet-sources) 64 | * [EONET.layers()](#eonet-layers) 65 | 66 | ## EPIC - Earth Polychromatic Imaging Camera 67 | * [EPIC.fetch()](#epic-fetch) 68 | * [EPIC.date()](#epic-date) 69 | * [EPIC.all()](#epic-all) 70 | * [EPIC.available()](#epic-available) 71 | 72 | ## Fireballs - Visible Meteor Events 73 | * [Fireballs.fetch()](#fireballs-fetch) 74 | 75 | ## Images - NASA Media and Video Assets 76 | * [Images.search()](#images-search) 77 | * [Images.asset()](#images-asset) 78 | * [Images.metadata()](#images-metadata) 79 | * [Images.captions()](#images-captions) 80 | 81 | ## Mars Photos - Photos from Mars Rovers 82 | * [MarsPhotos.fetch()](#marsphotos-fetch) 83 | * [MarsPhotos.manifest()](#marsphotos-manifest) 84 | 85 | ## NEO - Near Earth Objects 86 | * [NEO.feed()](#neo-feed) 87 | * [NEO.feedToday()](#neo-feedtoday) 88 | * [NEO.fetch()](#neo-fetch) 89 | * [NEO.browse()](#neo-browse) 90 | * [NEO.stats()](#neo-stats) 91 | 92 | ## NHATS - Near-Earth Object Human Space Flight Accessible Targets Study 93 | * [NHATS.fetch()](#nhats-fetch) 94 | 95 | ## Patents - NASA's Patent Portfolio 96 | * [Patents.fetch()](#patents-fetch) 97 | 98 | ## Scout - Trajectory Analysis and Hazard Assessment for Recently Detected Objects on the Minor Planet Center’s NEOCP 99 | * [Scout.fetch()](#scout-fetch) 100 | 101 | ## Sentry - Earth Impact Monitoring 102 | * [Sentry.fetch()](#sentry-fetch) 103 | 104 | ## Sounds - Sounds from Space 105 | * [Sounds.fetch()](#sounds-fetch) 106 | 107 | - - - 108 |

APOD.fetch(options)

109 | 110 | returns information for the [Astronomy Picture of the Day](https://apod.nasa.gov/apod/astropix.html) 111 | 112 | ##### `options` (optional) - **[Object]** 113 | * `date` - **[String]** The date of the APOD image to retrieve. Default is today's date Must be in the format `YYYY-MM-DD` 114 | * `hd` - **[Boolean]** Determines if the the URL for the high resolution image should be fetched. Default is `false` 115 | 116 | ```javascript 117 | APOD 118 | .fetch(options) 119 | .then(data => console.log(data)) 120 | .catch(err => console.log(err)); 121 | ``` 122 | 123 |

CAD.fetch(options)

124 | 125 | returns information current close-approach data for all asteroids and comets in JPL’s [SBDB](https://ssd.jpl.nasa.gov/sbdb.cgi) (Small-Body DataBase) 126 | 127 | Most options are filters effectively limiting the data to those matching the constraints, a few are object selectors (limit data to those matching the specified object), and one is a sort key. Filter-type options are "additive" in that they are combined with logical `AND` when applied to the data. Boolean-type options are only applied when `true`. For example, setting `options.neo = false` simply disables that filter (it does not select non-NEOs). 128 | 129 | For additional information, see the [API Documentation](https://ssd-api.jpl.nasa.gov/doc/cad.html) 130 | 131 | ##### `options` (optional) - **[Object]** 132 | * `date-min` - **[String]** Exclude data earlier than this date Must be in the format `YYYY-MM-DD` or `YYYY-MM-DDThh:mm:ss` or `now` for the current date. Defaults to `now` 133 | * `date-max` - **[String]** Exclude data later than this date Must be in the format `YYYY-MM-DD` or `YYYY-MM-DDThh:mm:ss` or `now` for the current date or `+D` for "D" days after now. Defaults to `+60` 134 | * `dist-min` - **[String]** Exclude data with an approach distance less than this, e.g., `0.05`, `10LD` (default units: au) 135 | * `dist-max` - **[String]** Exclude data with an approach distance greater than this (see `dist-min`) 136 | * `h-min` - **[Number]** Exclude data from objects with H-values less than this 137 | * `h-max` - **[Number]** Exclude data from objects with H-values greater than this 138 | * `v-inf-min` - **[Number]** Exclude data with V-infinity less than this positive value in km/s 139 | * `v-inf-max` - **[Number]** Exclude data with V-infinity greater than this positive value in km/s 140 | * `v-rel-min` - **[Number]** Exclude data with V-relative less than this positive value in km/s 141 | * `v-rel-max` - **[Number]** Exclude data with V-relative greater than this positive value in km/s 142 | * `class` - **[String]** Limit data to objects with the specified orbit-class (see list of valid class names below) 143 | * `pha` - **[Boolean]** Limit data to PHAs 144 | * `nea` - **[Boolean]** Limit data to NEAs 145 | * `comet` - **[Boolean]** Limit data to comets 146 | * `nea-coment` - **[Boolean]** Limit data to NEAs and comets 147 | * `neo` - **[Boolean]** Limit data to NEOs 148 | * `kind` - **[String]** Limit data to objects of the specified kind (`a`=asteriod, `an`=numbered-asteroids, `au`=unnumbered-asteroids, `c`=comets, `cn`=numbered-comets, `cu`=unnumbered-comets, `n`=numbered-objects, and `u`=unnumbered-objects) 149 | * `spk` - **[Number]** Only show data for the object matching this SPK-ID (e.g., `2000433` ) 150 | * `des` - **[String]** Only show data for the object matching this designation (e.g., `2015 AB`, `141P` or `433`) 151 | * `body` - **[String]** Limit data to close-approaches to the specified body (e.g., `Earth`) or allow all bodies with `ALL` or `*` (see list of valid bodies below) 152 | * `sort` - **[String]** Sort data on the specified field: `date`, `dist`, `dist-min`, `v-inf`, `v-rel`, `h`, or `object`. Default sort order is ascending, but you can prepend the value with `-` for descending. Default value is `-date` 153 | * `limit` - **[Number]** Limit data to the first N results (where N is the specified number and must be an integer value greater than zero) 154 | * `fullname` - **[Boolean]** Include the full-format object name/designation 155 | 156 | 157 | ##### SBDB Orbit Class Values 158 | Valid class names for the `class` option 159 | * `IEO` - **Atira** - an asteroid orbit contained entirely within the orbit of the Earth (Q < 0.983 AU). Also known as an Interior Earth Object. 160 | * `ATE` - **Aten** - Near-Earth asteroid orbits similar to that of 2062 Aten (a < 1.0 AU; Q > 0.983 AU). 161 | * `APO` - **Apollo** - Near-Earth asteroid orbits which cross the Earth’s orbit similar to that of 1862 Apollo (a > 1.0 AU; q < 1.017 AU). 162 | * `AMO` - **Amor** - Near-Earth asteroid orbits similar to that of 1221 Amor (1.017 AU < q < 1.3 AU). 163 | * `MCA` - **Mars-crossing Asteroid** - asteroids that cross the orbit of Mars constrained by (1.3 AU < q < 1.666 AU; a < 3.2 AU). 164 | * `IMB` - **Inner Main-belt Asteroid** - asteroids with orbital elements constrained by (a < 2.0 AU; q > 1.666 AU). 165 | * `MBA` - **Main-belt Asteroid** - asteroids with orbital elements constrained by (2.0 AU < a < 3.2 AU; q > 1.666 AU). 166 | * `OMB` - **Outer Main-belt Asteroid** - asteroids with orbital elements constrained by (3.2 AU < a < 4.6 AU). 167 | * `TJN` - **Jupiter Trojan** - asteroids trapped in Jupiter’s L4/L5 Lagrange points (4.6 AU < a < 5.5 AU; e < 0.3). 168 | * `CEN` - **Centaur Objects** - objects with orbits between Jupiter and Neptune (5.5 AU < a < 30.1 AU). 169 | * `TNO` - **TransNeptunian Object** - objects with orbits outside Neptune (a > 30.1 AU). 170 | * `PAA` - **Parabolic Asteroid** - asteroids on parabolic orbits (e = 1.0). 171 | * `HYA` - **Hyperbolic Asteroid** - asteroids on hyperbolic orbits (e > 1.0). 172 | * `HYP` - **Hyperbolic Comet** - comets on hyperbolic orbits (e > 1.0). 173 | * `PAR` - **Parabolic Comet** - comets on parabolic orbits (e = 1.0). 174 | * `COM` - **Comet** - comet orbit not matching any defined orbit class. 175 | * `JFC` - **Jupiter-family Comet** - classical definition (P < 20 y). 176 | * `HTC` - **Halley-type Comet** - classical definition (20 y < P < 200 y). 177 | * `ETc` - **Encke-type Comet** - as defined by Levison and Duncan (Tj > 3; a < aJ). 178 | * `CTc` - **Chiron-type Comet** - as defined by Levison and Duncan (Tj > 3; a > aJ). 179 | * `JFc` - **Jupiter-family Comet** - as defined by Levison and Duncan (2 < Tj < 3). 180 | 181 | ##### Close Approach Bodies 182 | The following bodies may be selected via the `body` query parameter. 183 | * `Merc` - Mercury 184 | * `Venus` - Venus 185 | * `Earth` - Earth 186 | * `Mars` - Mars 187 | * `Juptr` - Jupiter 188 | * `Satrn` - Saturn 189 | * `Urnus` - Uranus 190 | * `Neptn` - Neptune 191 | * `Pluto` - Pluto 192 | * `Moon` - Moon 193 | 194 | ```javascript 195 | CAD 196 | .fetch({ 197 | // prop names with hyphens require quotes 198 | 'date-min': '2015-04-03', 199 | 'date-max': '+20', 200 | body: 'Satrn', 201 | }) 202 | .then(data => console.log(data)) 203 | .catch(err => console.log(err)); 204 | ``` 205 | 206 |

Earth.imagery(options)

207 | 208 | Retrieves the Landsat 8 image for the supplied location and date 209 | 210 | ##### `options` (optional) - **[Object]** 211 | * `lat` - **[Number]** The latitude of the imagery's location to retrieve. 212 | * `lon` - **[Number]** The longitude of the imagery's location to retrieve. 213 | * `date` - **[String]** The date of the imagery to retrieve. Default is today's date. Must be in the format `YYYY-MM-DD` 214 | * `cloud_score` - **[Boolean]** Cloud score calculates the percentage of the image covered by clouds when `true`. Default is `false`. 215 | 216 | ```javascript 217 | Earth 218 | .imagery({ 219 | lon: 100.75, 220 | lat: 1.5, 221 | date: '2014-02-01', 222 | cloud_score: true, 223 | }) 224 | .then(data => console.log(data)) 225 | .catch(err => console.log(err)); 226 | ``` 227 | 228 |

Earth.assets(options)

229 | 230 | Retrieves the date-times and asset names for available imagery for a supplied location 231 | 232 | ##### `options` (optional) - **[Object]** 233 | * `lat` - **[Number]** The latitude of the asset's location to retrieve. 234 | * `lon` - **[Number]** The longitude of the asset's location to retrieve. 235 | * `begin` - **[String]** The beginning date of the asset to retrieve. Must be in the format `YYYY-MM-DD` 236 | * `end` - **[String]** The ending date of the asset to retrieve. Default is today's date. Must be in the format `YYYY-MM-DD` 237 | 238 | ```javascript 239 | Earth 240 | .assets({ 241 | lon: 100.75, 242 | lat: 1.5, 243 | begin: '2014-02-01', 244 | }) 245 | .then(data => console.log(data)) 246 | .catch(err => console.log(err)); 247 | ``` 248 | 249 |

EONET.events(options)

250 | 251 | Retrieves a single or list of natural Events recorded by [EONET](https://eonet.sci.gsfc.nasa.gov/) 252 | 253 | ##### `options` (optional) - **[Object]** 254 | * `eventId` - **[String]** ID of the Event. Pass this property if you are wanting to fetch a single event 255 | * `source` - **[String]** Filter events by Source ID. Multiple Source IDs can be included in the request via CSV (i.e '`InciWeb,EO`') 256 | * `status` - **[String]** `open|closed`. Filter events by only-open or only-closed. Default is `open`. 257 | * `limit` - **[Number]** Limits the number of events returned 258 | * `days` - **[Number]** Limit the number of of prior days (including today) from which events will be returned 259 | 260 | ```javascript 261 | EONET 262 | .events({ 263 | eventId: 'EONET_2763' 264 | source: 'UNISYS', 265 | status: 'open', 266 | limit: 5, 267 | days: 20, 268 | }) 269 | .then(data => console.log(data)) 270 | .catch(err => console.log(err)); 271 | ``` 272 | 273 |

EONET.categories(options)

274 | 275 | Retrieves a single or list of types of events by which individual events are cataloged. 276 | 277 | ##### `options` (optional) - **[Object]** 278 | * `categoryId` - **[Number]** ID of the Category. Pass this property if you are wanting to fetch a single category of events 279 | * `source` - **[String]** Filter categorized events by Source ID. Multiple Source IDs can be included in the request via CSV (i.e '`InciWeb,EO`') 280 | * `status` - **[String]** `open|closed`. Filter categorized events by only-open or only-closed. Default is `open`. 281 | * `limit` - **[Number]** Limits the number of categorized events returned 282 | * `days` - **[Number]** Limit the number of of prior days (including today) from which categorized events will be returned 283 | 284 | ```javascript 285 | EONET 286 | .categories({ 287 | categoryId: 14, 288 | source: 'InciWeb,EO', 289 | status: 'open', 290 | limit: 5, 291 | days: 20, 292 | }) 293 | .then(data => console.log(data)) 294 | .catch(err => console.log(err)); 295 | ``` 296 | 297 |

EONET.sources()

298 | 299 | Retrieves a list of references for further information about an event. 300 | 301 | ```javascript 302 | EONET 303 | .sources() 304 | .then(data => console.log(data)) 305 | .catch(err => console.log(err)); 306 | ``` 307 | 308 |

EONET.layers(options)

309 | 310 | Retrieves a list of references to a specific web service (e.g., WMS, WMTS) that can be used to produce imagery of a particular NASA data parameter. 311 | 312 | ##### `options` (optional) - **[Object]** 313 | * `categoryId` - **[Number]** ID of the Category by which to filter the Layers. 314 | 315 | ```javascript 316 | EONET 317 | .layers({ 318 | categoryId: 8 319 | }) 320 | .then(data => console.log(data)) 321 | .catch(err => console.log(err)); 322 | ``` 323 | 324 |

EPIC.fetch(type)

325 | 326 | Retrieves a list of the most recent date of natural or enhanced color imagery 327 | 328 | ##### `type` (required) - **[String]** 329 | 330 | Type of color imagery to fetch. Valid types are `natural` and `enhanced` 331 | 332 | ```javascript 333 | EPIC 334 | .fetch('natural') 335 | .then(data => console.log(data)) 336 | .catch(err => console.log(err)); 337 | ``` 338 | 339 |

EPIC.date(type, date)

340 | 341 | Retrieves a list of natural or enhanced color imagery available for the specified date 342 | 343 | ##### `type` (required) - **[String]** 344 | 345 | Type of color imagery to fetch. Valid types are `natural` and `enhanced` 346 | 347 | ##### `date` (required) - **[String]** 348 | 349 | The date of the `natural` or `enhanced` imagery to retrieve. Must be in the format `YYYY-MM-DD` 350 | 351 | ```javascript 352 | EPIC 353 | .date('enhanced', '2017-04-10') 354 | .then(data => console.log(data)) 355 | .catch(err => console.log(err)); 356 | ``` 357 | 358 |

EPIC.all(type)

359 | 360 | Retrieves a list of all dates with available `natural` or `enhanced` imagery 361 | 362 | ##### `type` (required) - **[String]** 363 | 364 | Type of color imagery to fetch. Valid types are `natural` and `enhanced` 365 | 366 | ```javascript 367 | EPIC 368 | .all('natural') 369 | .then(data => console.log(data)) 370 | .catch(err => console.log(err)); 371 | ``` 372 | 373 |

EPIC.available(type)

374 | 375 | Retrieves an alternate listing of all dates with available `natural` or `enhanced` color imagery 376 | 377 | ##### `type` (required) - **[String]** 378 | 379 | Type of color imagery to fetch. Valid types are `natural` and `enhanced` 380 | 381 | ```javascript 382 | EPIC 383 | .available('enhanced') 384 | .then(data => console.log(data)) 385 | .catch(err => console.log(err)); 386 | ``` 387 | 388 |

Fireballs.fetch(options)

389 | 390 | Get a list of Fireball events and their associated data. Be sure to reference the [API Documentation](https://ssd-api.jpl.nasa.gov/doc/fireball.html) for more information on Fireballs. 391 | 392 | ##### `options` (required) - **[Object]** 393 | * `date-min` - **[String]** exclude data earlier than this date. Must be in `YYYY-MM-DD` or `YYYY-MM-DDThh:mm:ss` format 394 | * `date-max` - **[String]** exclude data later than this date. Must be in `YYYY-MM-DD` or `YYYY-MM-DDThh:mm:ss` format 395 | * `energy-min` - **[Number]** exclude data with total-radiated-energy less than this positive value in joules ×1010 (e.g., `0.3` = 0.3×1010 joules) 396 | * `energy-max` - **[Number]** exclude data with total-radiated-energy greater than this (see `energy-min`) 397 | * `impact-e-min` - **[Number]** exclude data with estimated impact energy less than this positive value in kilotons (kt) (e.g., `0.08` kt) 398 | * `impact-e-max` - **[Number]** exclude data with total-radiated-energy greater than this (see impact-e-min) 399 | * `vel-min` - **[Number]** exclude data with velocity-at-peak-brightness less than this positive value in km/s (e.g., `18.5`) 400 | * `vel-max` - **[Number]** exclude data with velocity-at-peak-brightness greater than this positive value in km/s (e.g., `20`) 401 | * `alt-min` - **[Number]** exclude data from objects with an altitude less than this 402 | * `alt-max` - **[Number]** exclude data from objects with an altitude greater than this 403 | * `req-loc` - **[Boolean]** location (latitude and longitude) required; when set to `true`, exclude data without a location 404 | * `req-alt` - **[Boolean]** altitude required; when set to `true`, exclude data without an altitude 405 | * `req-vel` - **[Boolean]** velocity required; when set to `true`, exclude data without a velocity 406 | * `req-vel-comp` - **[Boolean]** velocity components required; when set to `true`, exclude data without velocity components 407 | * `sort` - **[String]** sort data on the specified field: `date`, `energy`, `impact-e`, `vel`, or `alt`. Default sort order is ascending, but you can prepend the value with `-` for descending. Default value is `-date` 408 | * `limit` - **[Number]** limit data to the first N results (where N is the specified number and must be an integer value greater than zero) 409 | * `fullname` - **[Boolean]** include the full-format object name/designation 410 | 411 | ```javascript 412 | Fireballs 413 | .fetch({ 414 | // prop names with hyphens require quotes 415 | 'date-min': '2015-04-03', 416 | 'req-loc': true 417 | }) 418 | .then(data => console.log(data)) 419 | .catch(err => console.log(err)); 420 | ``` 421 | 422 | 423 | 424 | Retrieves results and information on how to retrieve more details on images taken by astronauts. For additional information, the [API Documentation](https://images.nasa.gov/docs/images.nasa.gov_api_docs.pdf) 425 | 426 | ##### `options` (required) - **[Object]** Atleast one option property is required, but all individual options are optional 427 | * `q` - **[String]** Free text search terms to compare to all indexed metadata 428 | * `center` - **[String]** NASA center which published the media 429 | * `description` - **[String]** Terms to search for in `Description` fields 430 | * `keywords` - **[String]** Terms to search for in `Keywords` fields. Separate multiple values with commas 431 | * `location` - **[String]** Terms to search for in `Location` fields 432 | * `media_type` - **[String]** Media types to restrict the search to. Available types: [`image`, `audio`]. Separate multiple values with commas 433 | * `nasa_id` - **[String]** The media asset’s NASA ID 434 | * `photographer` - **[String]** The primary photographer’s name 435 | * `secondary_creator` - **[String]** A secondary photographer/videographer’s name 436 | * `title` - **[String]** Terms to search for in `Title` fields 437 | * `year_start` - **[String]** The start year for results. Must be in `YYYY` format 438 | * `year_end` - **[String]** The end year for results. Must be in `YYYY` format 439 | 440 | ```javascript 441 | Images 442 | .search({ 443 | q: 'Apollo 11', 444 | description: 'moon landing', 445 | media_type: 'image', 446 | }) 447 | .then(data => console.log(data)) 448 | .catch(err => console.log(err)); 449 | ``` 450 | 451 |

Images.asset(nasaId)

452 | Get a media asset's manifest for the given NASA ID 453 | 454 | ##### nasaId (required) - **[String]** The media asset’s NASA ID 455 | 456 | ```javascript 457 | Images 458 | .asset('as11-40-5874') 459 | .then(data => console.log(data)) 460 | .catch(err => console.log(err)); 461 | ``` 462 | 463 |

Images.metadata(nasaId)

464 | Get a media asset's metadata location for the given NASA ID 465 | 466 | ##### nasaId (required) - **[String]** The media asset’s NASA ID 467 | 468 | ```javascript 469 | Images 470 | .metadata('as11-40-5874') 471 | .then(data => console.log(data)) 472 | .catch(err => console.log(err)); 473 | ``` 474 | 475 |

Images.captions(nasaId)

476 | Get a video asset's captions location for the given NASA ID 477 | 478 | ##### nasaId (required) - **[String]** The media asset’s NASA ID 479 | 480 | ```javascript 481 | Images 482 | .captions('172_ISS-Slosh') 483 | .then(data => console.log(data)) 484 | .catch(err => console.log(err)); 485 | ``` 486 | 487 |

MarsPhotos.fetch(roverName, options)

488 | Get a list of photos from a Mars Rover on a particular Sol/Earth Day 489 | 490 | ##### `rover` (required) - **[String]** 491 | Rover to fetch photos from. Valid rover names are `curiosity`, `opportunity`, `spirit`, and `perseverance` 492 | 493 | ##### `options` (required) - **[Object]** 494 | * `sol` - **[Number]** Martian day on which photos were taken, relative to when the rover arrived on Mars, starting at `0`. If the `sol` option is not provided, `earth_date` must be provided instead. 495 | * `earth_date` - **[String]** Date on which photos were taken. If the `earth_date` option is not provided, `sol` must be provided. Must be in `YYYY-MM-DD` format. 496 | * `camera` - **[String]** Filter results for photos from a specific camera. See [this rover camera table](https://github.com/chrisccerami/mars-photo-api#cameras) for a list of available cameras on each rover 497 | * `page` - **[Number]** Page number to fetch from paginated results 498 | 499 | ```javascript 500 | MarsPhotos 501 | .fetch('curiosity', { 502 | camera: 'navcam', 503 | sol: 10 504 | }) 505 | .then(data => console.log(data)) 506 | .catch(err => console.log(err)); 507 | ``` 508 | 509 |

MarsPhotos.manifest(roverName)

510 | Get a manifest for a Mars Rover 511 | 512 | ##### `rover` (required) - **[String]** 513 | Rover to fetch manifest for. Valid rover names are `curiosity`, `opportunity`, `spirit`, and `perseverance` 514 | 515 | ```javascript 516 | MarsPhotos 517 | .manifest('curiosity') 518 | .then(data => console.log(data)) 519 | .catch(err => console.log(err)); 520 | ``` 521 | 522 |

NEO.feed(options)

523 | Get a list of Near Earth Objects within a date range. The max range for one query is 7 days. 524 | 525 | ##### `options` (optional) - **[Object]** 526 | * `start_date` - **[String]** Starting date for asteroid search. Default is today's date. Must be in the format `YYYY-MM-DD` 527 | * `end_date` - **[String]** End date for asteroid search. Default is 7 days after `start_date`. Must be in the format `YYYY-MM-DD` 528 | * `detailed` - **[Boolean]** Determine is additional details for asteroids should be included. Default is `false` 529 | 530 | ```javascript 531 | NEO 532 | .feed({ 533 | start_date: '2016-06-12', 534 | end_date: '2016-06-15' 535 | }) 536 | .then(data => console.log(data)) 537 | .catch(err => console.log(err)); 538 | ``` 539 | 540 |

NEO.feedToday(options)

541 | Get a list of Near Earth Objects for today. The max range for one query is 7 days. 542 | 543 | ##### `options` (optional) - **[Object]** 544 | * `detailed` - **[Boolean]** Determine is additional details for asteroids should be included. Default is `false` 545 | 546 | ```javascript 547 | NEO 548 | .feedToday() 549 | .then(data => console.log(data)) 550 | .catch(err => console.log(err)); 551 | ``` 552 | 553 |

NEO.fetch(asteroidId)

554 | Retieve a Near Earth Object with a given id 555 | 556 | ##### `asteroidId` (required) - **[String]** ID of NEO 557 | 558 | ```javascript 559 | NEO 560 | .fetch('3729835') 561 | .then(data => console.log(data)) 562 | .catch(err => console.log(err)); 563 | ``` 564 | 565 |

NEO.browse()

566 | Retieve a paginated list of Near Earth Objects 567 | 568 | ##### `options` (optional) - **[Object]** 569 | * `page` - **[Number]** Page number (zero-indexed) 570 | * `size` - **[Number]** Number of NEOs per page 571 | 572 | ```javascript 573 | NEO 574 | .browse({ 575 | page: 2, 576 | size: 20 577 | }) 578 | .then(data => console.log(data)) 579 | .catch(err => console.log(err)); 580 | ``` 581 | 582 |

NEO.stats()

583 | 584 | Retieve Near Earth Object statistics 585 | 586 | ```javascript 587 | NEO 588 | .stats() 589 | .then(data => console.log(data)) 590 | .catch(err => console.log(err)); 591 | ``` 592 | 593 |

NHATS.fetch(options)

594 | 595 | Retrieve of list of Near-Earth Asteroids (NEAs) that might be accessible by future human space flight missions. 596 | 597 | The NHATS API employs various "modes" to obtain required data. This results in restrictions on the combination of options you can use in a single request. For detailed information on this, refer the the [API Documentation](https://ssd-api.jpl.nasa.gov/doc/nhats.html) 598 | 599 | ##### `options` (optional) - **[Object]** 600 | * `dv` - **[Number]** Minimum total delta-V (km/s). Allowed values are `4`, `5`, `6`, `7`, `8`, 601 | `9`, `10`, `11`, `12`. Default value is `12` 602 | * `dur` - **[Number]** Minimum total duration (days). Allowed values are `60`, `90`, `120`, `150`, `180`, `210`, `240`, `270`, `300`, `330`, `360`, `390`, `420`, `450`. Default value is `450` 603 | * `stay` - **[Number]** Minimum stay (days). Allowed values are `8`, `16`, `24`, `32`. Default is `8` 604 | * `launch` - **[String]** Launch window (year range). Allow values are `2015-2020`, `2020-2025`, `2025-2030`, `2030-2035`, `2035-2040`, `2015-2040` 605 | * `h` - **[Number]** Object’s maximum absolute magnitude, H (mag). Allowed values are `16`, `17`, `18`, `19`, `20`, `21`, `22`, `23`, `24`, `25`, `26`, `27`, `28`, `29`, `30` 606 | * `occ` - **[Number]** Object’s maximum orbit condition code (OCC). Allowed values are `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8` 607 | * `spk` - **[Number/String]** Select data for the object matching this SPK-ID (e.g., `2000433`). 608 | * `des` - **[String]** Select data for the object matching this designation (e.g., `2015 AB`, `141P`, or `433`) 609 | * `plot` - **[Boolean]** Include base-64 encoded plot image file content via output field `plot_base64` 610 | 611 | ```javascript 612 | NHATS 613 | .fetch({ 614 | dv: 5, 615 | plot: true, 616 | }) 617 | .then(data => console.log(data)) 618 | .catch(err => console.log(err)); 619 | ``` 620 | 621 |

Patents.fetch(options)

622 | 623 | Retrieve of list of patents from NASA's patent portfolio 624 | 625 | ##### `options` (optional) - **[Object]** 626 | * `query` - **[String]** Search text to filter results 627 | * `concept_tags` - **[Boolean]** Return an ordered dictionary of concepts from the patent abstract. Default is `false` 628 | * `limit` - **[Number]** Maximum number of patents to return. If omitted, all found patents will be returned. 629 | 630 | ```javascript 631 | Patents 632 | .fetch({ 633 | query: 'temperature', 634 | concept_tags: true, 635 | }) 636 | .then(data => console.log(data)) 637 | .catch(err => console.log(err)); 638 | ``` 639 | 640 |

Scout.fetch(options)

641 | 642 | Returns a list of Near-Earth Objects (NEOs) with trajectory analysis and hazard assessment for recently detected objects on the Minor Planet Center’s Near-Earth Object Confirmation Page (NEOCP). 643 | 644 | The Scout API employs various "modes" to obtain required data. This results in restrictions on the combination of options you can use in a single request. For detailed information on this, refer the the [API Documentation](https://ssd-api.jpl.nasa.gov/doc/scout.html) 645 | 646 | ##### `options` (optional) - **[Object]** 647 | * `tdes` - **[String]** Select data for the NEOCP object matching this temporary designation (e.g., `P10uUSw`) 648 | * `plot` - **[String]** Get plot files for the specified NEOCP object of the selected type (`el`=elements, `ca`=close-approach, `sr`=systematic-ranging). Multiple values may be passed with a `:` delimiter. For example, `ca:el`. Results are Base64-encoded image data. 649 | * `file` - **[String]** Get the list of available data files (when file=`list`) or get the requested data file for the specified NEOCP object. 650 | * `orbits` - **[Boolean]** Get sampled orbits data for the specified NEOCP object 651 | * `n-orbits` - **[Number]** Limit the number of sampled orbits to this value. Must be in the range `[1:1000]` 652 | * `eph-start` - **[String]** Get the ephemeris for the specified NEOCP object at this time UTC. See API Docs for valid Date/Time formats 653 | * `eph-stop` - **[String]** Set the ephemeris stop-time (if specified, requires `eph-start` and must be later than `eph-start`). See API Docs for valid Date/Time formats 654 | * `eph-step` - **[String]** Set the ephemeris step-size (if specified, requires both `eph-start` and `eph-stop`; if not specified, set to the span). Valid formats are `#d`, `#h`, `#m` (where `#` is a positive definite integer) 655 | * `obs-code` - **[String]** Get the ephemeris for the specified NEOCP object relative to the specified MPC observatory code. Must be a valid MPC code 656 | * `fov-diam` - **[Number]** Specify the size (diameter) of the field-of-view in arc-minutes. Must be in the range `(0:1800]` 657 | * `fov-ra` - **[String]** Specify the field-of-view center (R.A. component) [requires `fov-diam` and `fov-dec`; invalid if `eph-stop` is set]. See API Docs for valid formats 658 | * `fov-dec` - **[String]** specify the field-of-view center (Dec. component) [requires `fov-diam` and `fov-ra`; invalid if `eph-stop` is set]. See API Docs for valid formats 659 | * `fov-vmag` - **[Number]** Filter ephemeris results to those with V-magnitude of this value or brighter [requires `fov-diam`]. Must be in the range `[0:40]` 660 | 661 | 662 | ```javascript 663 | Scout 664 | .fetch({ 665 | plot: 'el', 666 | orbits: true, 667 | }) 668 | .then(data => console.log(data)) 669 | .catch(err => console.log(err)); 670 | ``` 671 | 672 |

Sentry.fetch(options)

673 | 674 | Returns a list of Near-Earth Asteroids (NEAs) that could potentially impact the Earth in the next 100 years. 675 | 676 | The Sentry API employs various "modes" to obtain required data. This results in restrictions on the combination of options you can use in a single request. For detailed information on this, refer the the [API Documentation](https://ssd-api.jpl.nasa.gov/doc/sentry.html) 677 | 678 | ##### `options` (optional) - **[Object]** 679 | * `spk` - **[Number]** Select data for the object matching this SPK-ID (e.g., `2029075` ) 680 | * `des` - **[String]** Select data for the object matching this designation (e.g., `29075` or `2000 SG344`) [Note: basename-form may also be used, e.g., `a29075` or `2000sg344`] 681 | * `h-max` - **[Number]** Limit data to those with an absolute magnitude, H (weighted-mean for mode-S) less than or equal to this value. Accepted range is [-10:100] 682 | * `ps-min` - **[Number]** Limit data to those with a (weighted-mean for mode-S) Palermo scale (PS) greater than or equal to this value. Accepted range is [-20:20] 683 | * `ip-min` - **[Number]** Limit data to those with a (weighted-mean for mode-S) impact-probability (IP) greater than or equal to this value. Accepted range is [1:1e^-10] 684 | * `days` - **[Number]** Number of days since last observation: limit data to those objects that have been observed within the specified number of days (if the number is negative, limit data to those which have not been observed with the specified number of days). Accepted values meet the criterion `ABS(days) > 6` 685 | * `all` - **[Boolean]** Request the complete VI data set 686 | * `removed` - **[Boolean]** Request the list of removed objects 687 | 688 | ```javascript 689 | Sentry 690 | .fetch({ 691 | all: true 692 | }) 693 | .then(data => console.log(data)) 694 | .catch(err => console.log(err)); 695 | ``` 696 | 697 |

Sounds.fetch(options)

698 | Retrieve of list of audio resources containing sounds from space 699 | 700 | ##### `options` (optional) - **[Object]** 701 | * `q` - **[String]** Search text to filter results 702 | * `limit` - **[Number]** Maximum number of tracks to return. If omitted, all found tracks will be returned. 703 | 704 | ```javascript 705 | Sounds 706 | .fetch({ 707 | limit: 5 708 | }) 709 | .then(data => console.log(data)) 710 | .catch(err => console.log(err)); 711 | ``` 712 | -------------------------------------------------------------------------------- /lib/apod.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _promise = require('babel-runtime/core-js/promise'); 8 | 9 | var _promise2 = _interopRequireDefault(_promise); 10 | 11 | exports.default = apod; 12 | 13 | var _util = require('./util'); 14 | 15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 16 | 17 | function apod() { 18 | return { 19 | 20 | fetch: function fetch() { 21 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 22 | return new _promise2.default(function (resolve, reject) { 23 | if (options.hasOwnProperty('date') && !(0, _util.validateDate)(options.date)) { 24 | return reject(new Error('date must be in "YYYY-MM-DD" format')); 25 | } 26 | return (0, _util.sendRequest)('api.nasa.gov', '/planetary/apod', options, resolve, reject, _util.handleResult); 27 | }); 28 | } 29 | 30 | }; 31 | } 32 | module.exports = exports['default']; -------------------------------------------------------------------------------- /lib/cad.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _assign = require('babel-runtime/core-js/object/assign'); 8 | 9 | var _assign2 = _interopRequireDefault(_assign); 10 | 11 | var _promise = require('babel-runtime/core-js/promise'); 12 | 13 | var _promise2 = _interopRequireDefault(_promise); 14 | 15 | exports.default = cad; 16 | 17 | var _util = require('./util'); 18 | 19 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 20 | 21 | function cad() { 22 | function validateClass(className) { 23 | var validClasses = ['IEO', 'ATE', 'APO', 'AMO', 'MCA', 'IMB', 'MBA', 'OMB', 'TJN', 'CEN', 'TNO', 'PAA', 'HYA', 'HYP', 'PAR', 'COM', 'JFC', 'HTC', 'ETc', 'CTc', 'JFc']; 24 | return validClasses.indexOf(className) === -1; 25 | } 26 | 27 | function validateBody(body) { 28 | var validBodies = ['merc', 'venus', 'earth', 'mars', 'juptr', 'satrn', 'urnus', 'neptn', 'pluto', 'moon']; 29 | return validBodies.indexOf(body.toLowerCase()) === -1; 30 | } 31 | 32 | return { 33 | 34 | fetch: function fetch() { 35 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 36 | return new _promise2.default(function (resolve, reject) { 37 | var optionOverrides = {}; 38 | if (options.hasOwnProperty('date-min')) { 39 | if (!(0, _util.validateDate)(options['date-min']) && !(0, _util.validateDateTime)(options['date-min'])) { 40 | if (options['date-min'] !== 'now') { 41 | return reject(new Error('date-min is not in a valid format.')); 42 | } 43 | } 44 | } 45 | if (options.hasOwnProperty('date-max')) { 46 | if (!(0, _util.validateDate)(options['date-max']) && !(0, _util.validateDateTime)(options['date-max'])) { 47 | if (options['date-max'].match(/^[+]\d+$/)) { 48 | optionOverrides['date-max'] = options['date-max'].replace(/[+]/, '%2B'); 49 | } else if (options['date-max'] !== 'now') { 50 | return reject(new Error('date-max is not in a valid format.')); 51 | } 52 | } 53 | } 54 | if (options.hasOwnProperty('class')) { 55 | if (!validateClass(options.class)) return reject(new Error('Invalid class value')); 56 | } 57 | if (options.hasOwnProperty('body')) { 58 | if (!validateBody(options.body)) return reject(new Error('Invalid body value')); 59 | } 60 | return (0, _util.sendRequest)('ssd-api.jpl.nasa.gov', '/cad.api', (0, _assign2.default)({}, options, optionOverrides), resolve, reject, _util.handleResult, true); 61 | }); 62 | } 63 | 64 | }; 65 | } 66 | module.exports = exports['default']; -------------------------------------------------------------------------------- /lib/config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | var apiKey = process.env.NASA_API_KEY; 7 | var setNasaApiKey = function setNasaApiKey(key) { 8 | exports.apiKey = apiKey = key; 9 | return null; 10 | }; 11 | 12 | exports.apiKey = apiKey; 13 | exports.setNasaApiKey = setNasaApiKey; -------------------------------------------------------------------------------- /lib/earth.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _promise = require('babel-runtime/core-js/promise'); 8 | 9 | var _promise2 = _interopRequireDefault(_promise); 10 | 11 | exports.default = earth; 12 | 13 | var _util = require('./util'); 14 | 15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 16 | 17 | var baseurl = 'api.nasa.gov'; 18 | 19 | var endpointbase = '/planetary/earth/'; 20 | 21 | function earth() { 22 | return { 23 | 24 | imagery: function imagery() { 25 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 26 | return new _promise2.default(function (resolve, reject) { 27 | if (options.hasOwnProperty('date') && !(0, _util.validateDate)(options.date)) { 28 | return reject(new Error('date must be in "YYYY-MM-DD" format')); 29 | } 30 | return (0, _util.sendRequest)(baseurl, endpointbase + 'imagery', options, resolve, reject, _util.handleResult); 31 | }); 32 | }, 33 | 34 | assets: function assets() { 35 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 36 | return new _promise2.default(function (resolve, reject) { 37 | if (options.hasOwnProperty('begin') && !(0, _util.validateDate)(options.begin)) { 38 | return reject(new Error('date must be in "YYYY-MM-DD" format')); 39 | } 40 | if (options.hasOwnProperty('end') && !(0, _util.validateDate)(options.end)) { 41 | return reject(new Error('date must be in "YYYY-MM-DD" format')); 42 | } 43 | return (0, _util.sendRequest)(baseurl, endpointbase + 'assets', options, resolve, reject, _util.handleResult); 44 | }); 45 | } 46 | 47 | }; 48 | } 49 | module.exports = exports['default']; -------------------------------------------------------------------------------- /lib/eonet.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _promise = require('babel-runtime/core-js/promise'); 8 | 9 | var _promise2 = _interopRequireDefault(_promise); 10 | 11 | exports.default = eonet; 12 | 13 | var _util = require('./util'); 14 | 15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 16 | 17 | var baseurl = 'eonet.sci.gsfc.nasa.gov'; 18 | 19 | var endpointbase = '/api/v2.1/'; 20 | 21 | function eonet() { 22 | return { 23 | 24 | events: function events() { 25 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 26 | return new _promise2.default(function (resolve, reject) { 27 | var endpoint = endpointbase + 'events'; 28 | if (options.hasOwnProperty('eventId')) endpoint = endpoint + '/' + options.eventId; 29 | return (0, _util.sendRequest)(baseurl, endpoint, options, resolve, reject, _util.handleResult); 30 | }); 31 | }, 32 | 33 | categories: function categories() { 34 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 35 | return new _promise2.default(function (resolve, reject) { 36 | var endpoint = endpointbase + 'categories'; 37 | if (options.hasOwnProperty('categoryId')) endpoint = endpoint + '/' + options.categoryId; 38 | return (0, _util.sendRequest)(baseurl, endpoint, options, resolve, reject, _util.handleResult); 39 | }); 40 | }, 41 | 42 | sources: function sources() { 43 | return new _promise2.default(function (resolve, reject) { 44 | return (0, _util.sendRequest)(baseurl, endpointbase + 'sources', {}, resolve, reject, _util.handleResult); 45 | }); 46 | }, 47 | 48 | layers: function layers() { 49 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 50 | return new _promise2.default(function (resolve, reject) { 51 | var endpoint = endpointbase + 'layers'; 52 | if (options.hasOwnProperty('categoryId')) endpoint = endpoint + '/' + options.categoryId; 53 | return (0, _util.sendRequest)(baseurl, endpoint, {}, resolve, reject, _util.handleResult); 54 | }); 55 | } 56 | 57 | }; 58 | } 59 | module.exports = exports['default']; -------------------------------------------------------------------------------- /lib/epic.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = undefined; 7 | 8 | var _promise = require('babel-runtime/core-js/promise'); 9 | 10 | var _promise2 = _interopRequireDefault(_promise); 11 | 12 | var _util = require('./util'); 13 | 14 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 15 | 16 | var baseurl = 'api.nasa.gov'; 17 | 18 | var endpointbase = '/EPIC/api/'; 19 | 20 | function epic() { 21 | function validateType(type) { 22 | var validTypes = ['natural', 'enhanced']; 23 | var i = validTypes.indexOf(type.toLowerCase()); 24 | return i === -1 ? '' : validTypes[i]; 25 | } 26 | 27 | return { 28 | 29 | fetch: function fetch(type) { 30 | return new _promise2.default(function (resolve, reject) { 31 | if (!type) return reject(new Error('Image quality type is required')); 32 | var validType = validateType(type); 33 | if (!validType) return reject(new Error('Invalid image quality type')); 34 | return (0, _util.sendRequest)(baseurl, '' + endpointbase + validType, {}, resolve, reject, _util.handleResult); 35 | }); 36 | }, 37 | 38 | date: function date(type, _date) { 39 | return new _promise2.default(function (resolve, reject) { 40 | if (!type) return reject(new Error('Image quality type is required')); 41 | var validType = validateType(type); 42 | if (!validType) return reject(new Error('Invalid image quality type')); 43 | if (!_date) return reject(new Error('date is required')); 44 | if (!(0, _util.validateDate)(_date)) return reject(new Error('date must be in "YYYY-MM-DD" format')); 45 | return (0, _util.sendRequest)(baseurl, '' + endpointbase + type + '/date/' + _date, {}, resolve, reject, _util.handleResult); 46 | }); 47 | }, 48 | 49 | all: function all(type) { 50 | return new _promise2.default(function (resolve, reject) { 51 | if (!type) return reject(new Error('Image quality type is required')); 52 | var validType = validateType(type); 53 | if (!validType) return reject(new Error('Invalid image quality type')); 54 | return (0, _util.sendRequest)(baseurl, '' + endpointbase + type + '/all', {}, resolve, reject, _util.handleResult); 55 | }); 56 | }, 57 | 58 | available: function available(type) { 59 | return new _promise2.default(function (resolve, reject) { 60 | if (!type) return reject(new Error('Image quality type is required')); 61 | var validType = validateType(type); 62 | if (!validType) return reject(new Error('Invalid image quality type')); 63 | return (0, _util.sendRequest)(baseurl, '' + endpointbase + type + '/available', {}, resolve, reject, _util.handleResult); 64 | }); 65 | } 66 | 67 | }; 68 | } 69 | exports.default = epic; 70 | module.exports = exports['default']; -------------------------------------------------------------------------------- /lib/fireballs.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _promise = require('babel-runtime/core-js/promise'); 8 | 9 | var _promise2 = _interopRequireDefault(_promise); 10 | 11 | exports.default = fireballs; 12 | 13 | var _util = require('./util'); 14 | 15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 16 | 17 | function fireballs() { 18 | return { 19 | 20 | fetch: function fetch() { 21 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 22 | return new _promise2.default(function (resolve, reject) { 23 | if (options.hasOwnProperty('date-min')) { 24 | if (!(0, _util.validateDate)(options['date-min']) && !(0, _util.validateDateTime)(options['date-min'])) { 25 | return reject(new Error('date-min is not in a valid format.')); 26 | } 27 | } 28 | if (options.hasOwnProperty('date-max')) { 29 | if (!(0, _util.validateDate)(options['date-max']) && !(0, _util.validateDateTime)(options['date-max'])) { 30 | return reject(new Error('date-max is not in a valid format.')); 31 | } 32 | } 33 | return (0, _util.sendRequest)('ssd-api.jpl.nasa.gov', '/fireball.api', options, resolve, reject, _util.handleResult, true); 34 | }); 35 | } 36 | 37 | }; 38 | } 39 | module.exports = exports['default']; -------------------------------------------------------------------------------- /lib/images.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _keys = require('babel-runtime/core-js/object/keys'); 8 | 9 | var _keys2 = _interopRequireDefault(_keys); 10 | 11 | var _promise = require('babel-runtime/core-js/promise'); 12 | 13 | var _promise2 = _interopRequireDefault(_promise); 14 | 15 | exports.default = images; 16 | 17 | var _util = require('./util'); 18 | 19 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 20 | 21 | function images() { 22 | var baseurl = 'images-api.nasa.gov'; 23 | 24 | function validateMediaType(mediaType) { 25 | if (!mediaType || typeof mediaType !== 'string') return false; 26 | return mediaType.match(/^image$|^audio$|^image,audio$|^audio,image$/) !== null; 27 | } 28 | 29 | function validateYear(year) { 30 | if (!year || typeof year !== 'string') return false; 31 | return year.match(/^\d{4}$/) !== null; 32 | } 33 | 34 | return { 35 | 36 | search: function search() { 37 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 38 | return new _promise2.default(function (resolve, reject) { 39 | if (!(0, _keys2.default)(options).length) { 40 | return reject(new Error('Atleast one search param is required')); 41 | } 42 | if (options.hasOwnProperty('media_type') && !validateMediaType(options.media_type)) { 43 | return reject(new Error('media_type values must match image||audio||image,audio||audio,image')); 44 | } 45 | if (options.hasOwnProperty('year_start') && !validateYear(options.year_start)) { 46 | return reject(new Error('year_start must be in "YYYY" format')); 47 | } 48 | if (options.hasOwnProperty('year_end') && !validateYear(options.year_end)) { 49 | return reject(new Error('year_end must be in "YYYY" format')); 50 | } 51 | return (0, _util.sendRequest)(baseurl, '/search', options, resolve, reject, _util.handleResult, true); 52 | }); 53 | }, 54 | 55 | asset: function asset(nasaId) { 56 | return new _promise2.default(function (resolve, reject) { 57 | if (!nasaId) return reject(new Error('nasaId is required')); 58 | return (0, _util.sendRequest)(baseurl, '/asset/' + nasaId, {}, resolve, reject, _util.handleResult, true); 59 | }); 60 | }, 61 | 62 | metadata: function metadata(nasaId) { 63 | return new _promise2.default(function (resolve, reject) { 64 | if (!nasaId) return reject(new Error('nasaId is required')); 65 | return (0, _util.sendRequest)(baseurl, '/metadata/' + nasaId, {}, resolve, reject, _util.handleResult, true); 66 | }); 67 | }, 68 | 69 | captions: function captions(nasaId) { 70 | return new _promise2.default(function (resolve, reject) { 71 | if (!nasaId) return reject(new Error('nasaId is required')); 72 | return (0, _util.sendRequest)(baseurl, '/captions/' + nasaId, {}, resolve, reject, _util.handleResult, true); 73 | }); 74 | } 75 | 76 | }; 77 | } 78 | module.exports = exports['default']; -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.setNasaApiKey = exports.Sounds = exports.Sentry = exports.Scout = exports.Patents = exports.NHATS = exports.NEO = exports.MarsPhotos = exports.Images = exports.Fireballs = exports.EPIC = exports.EONET = exports.Earth = exports.CAD = exports.APOD = undefined; 7 | 8 | var _config = require('./config'); 9 | 10 | var APOD = require('./apod')(); 11 | var CAD = require('./cad')(); 12 | var Earth = require('./earth')(); 13 | var EONET = require('./eonet')(); 14 | var EPIC = require('./epic')(); 15 | var Fireballs = require('./fireballs')(); 16 | var Images = require('./images')(); 17 | var MarsPhotos = require('./mars-photos')(); 18 | var NEO = require('./neo')(); 19 | var NHATS = require('./nhats')(); 20 | var Patents = require('./patents')(); 21 | var Scout = require('./scout')(); 22 | var Sentry = require('./sentry')(); 23 | var Sounds = require('./sounds')(); 24 | 25 | exports.APOD = APOD; 26 | exports.CAD = CAD; 27 | exports.Earth = Earth; 28 | exports.EONET = EONET; 29 | exports.EPIC = EPIC; 30 | exports.Fireballs = Fireballs; 31 | exports.Images = Images; 32 | exports.MarsPhotos = MarsPhotos; 33 | exports.NEO = NEO; 34 | exports.NHATS = NHATS; 35 | exports.Patents = Patents; 36 | exports.Scout = Scout; 37 | exports.Sentry = Sentry; 38 | exports.Sounds = Sounds; 39 | exports.setNasaApiKey = _config.setNasaApiKey; -------------------------------------------------------------------------------- /lib/mars-photos.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _assign = require('babel-runtime/core-js/object/assign'); 8 | 9 | var _assign2 = _interopRequireDefault(_assign); 10 | 11 | var _promise = require('babel-runtime/core-js/promise'); 12 | 13 | var _promise2 = _interopRequireDefault(_promise); 14 | 15 | exports.default = marsPhotos; 16 | 17 | var _util = require('./util'); 18 | 19 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 20 | 21 | var baseurl = 'api.nasa.gov'; 22 | 23 | var endpointbase = '/mars-photos/api/v1/'; 24 | 25 | function marsPhotos() { 26 | function validateRover(rover) { 27 | var validRovers = ['curiosity', 'opportunity', 'spirit', 'perseverance']; 28 | var i = validRovers.indexOf(rover.toLowerCase()); 29 | return i === -1 ? '' : validRovers[i]; 30 | } 31 | 32 | function validateCamera(rover, camera) { 33 | var validCameras = { 34 | curiosity: ['fhaz', 'rhaz', 'mast', 'chemcam', 'mahli', 'mardi', 'navcam'], 35 | opportunity: ['fhaz', 'rhaz', 'navcam', 'pancam', 'minites'], 36 | spirit: ['fhaz', 'rhaz', 'navcam', 'pancam', 'minites'], 37 | perseverance: ['edl_rucam', 'edl_rdcam', 'edl_ddcam', 'edl_pucam1', 'edl_pucam2', 'navcam_left', 'navcam_right', 'mcz_right', 'mcz_left', 'front_hazcam_left_a', 'front_hazcam_right_a', 'rear_hazcam_left', 'rear_hazcam_right'] 38 | }; 39 | var i = validCameras[rover].indexOf(camera.toLowerCase()); 40 | return i === -1 ? '' : validCameras[rover][i]; 41 | } 42 | 43 | return { 44 | 45 | fetch: function fetch(rover) { 46 | var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 47 | return new _promise2.default(function (resolve, reject) { 48 | if (!rover) return reject(new Error('Rover name is required')); 49 | var validRover = validateRover(rover); 50 | if (!validRover) return reject(new Error('Invalid rover name')); 51 | var validCamera = void 0; 52 | if (options.hasOwnProperty('camera')) { 53 | validCamera = validateCamera(validRover, options.camera); 54 | if (!validCamera) return reject(new Error('Invalid camera name')); 55 | } 56 | if (!options.hasOwnProperty('sol') && !options.hasOwnProperty('earth_date')) { 57 | return reject(new Error('You must provide either earth_date or sol')); 58 | } 59 | if (options.hasOwnProperty('earth_date') && !(0, _util.validateDate)(options.earth_date)) { 60 | return reject(new Error('earth_date must be in "YYYY-MM-DD" format')); 61 | } 62 | return (0, _util.sendRequest)(baseurl, endpointbase + 'rovers/' + validRover + '/photos', (0, _assign2.default)({}, options, { camera: validCamera }), resolve, reject, _util.handleResult); 63 | }); 64 | }, 65 | 66 | manifest: function manifest(rover) { 67 | return new _promise2.default(function (resolve, reject) { 68 | if (!rover) return reject(new Error('Rover name is required')); 69 | var validRover = validateRover(rover); 70 | if (!validRover) return reject(new Error('Invalid rover name')); 71 | return (0, _util.sendRequest)(baseurl, endpointbase + 'manifests/' + validRover, {}, resolve, reject, _util.handleResult); 72 | }); 73 | } 74 | 75 | }; 76 | } 77 | module.exports = exports['default']; -------------------------------------------------------------------------------- /lib/neo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _promise = require('babel-runtime/core-js/promise'); 8 | 9 | var _promise2 = _interopRequireDefault(_promise); 10 | 11 | exports.default = neo; 12 | 13 | var _util = require('./util'); 14 | 15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 16 | 17 | var baseurl = 'api.nasa.gov'; 18 | 19 | var endpointbase = '/neo/rest/v1/'; 20 | 21 | function neo() { 22 | return { 23 | 24 | feed: function feed() { 25 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 26 | return new _promise2.default(function (resolve, reject) { 27 | if (options.hasOwnProperty('start_date') && !(0, _util.validateDate)(options.start_date)) { 28 | return reject(new Error('start_date must be in "YYYY-MM-DD" format')); 29 | } 30 | if (options.hasOwnProperty('end_date') && !(0, _util.validateDate)(options.end_date)) { 31 | return reject(new Error('end_date must be in "YYYY-MM-DD" format')); 32 | } 33 | return (0, _util.sendRequest)(baseurl, endpointbase + 'feed', options, resolve, reject, _util.handleResult); 34 | }); 35 | }, 36 | 37 | feedToday: function feedToday() { 38 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 39 | return new _promise2.default(function (resolve, reject) { 40 | return (0, _util.sendRequest)(baseurl, endpointbase + 'feed/today', options, resolve, reject, _util.handleResult); 41 | }); 42 | }, 43 | 44 | fetch: function fetch(asteroidId) { 45 | return new _promise2.default(function (resolve, reject) { 46 | if (!asteroidId) return reject(new Error('asteroidId is required')); 47 | return (0, _util.sendRequest)(baseurl, endpointbase + 'neo/' + asteroidId, {}, resolve, reject, _util.handleResult); 48 | }); 49 | }, 50 | 51 | browse: function browse() { 52 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 53 | return new _promise2.default(function (resolve, reject) { 54 | return (0, _util.sendRequest)(baseurl, endpointbase + 'neo/browse', options, resolve, reject, _util.handleResult); 55 | }); 56 | }, 57 | 58 | stats: function stats() { 59 | return new _promise2.default(function (resolve, reject) { 60 | return (0, _util.sendRequest)(baseurl, endpointbase + 'stats', {}, resolve, reject, _util.handleResult); 61 | }); 62 | } 63 | 64 | }; 65 | } 66 | module.exports = exports['default']; -------------------------------------------------------------------------------- /lib/nhats.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _promise = require('babel-runtime/core-js/promise'); 8 | 9 | var _promise2 = _interopRequireDefault(_promise); 10 | 11 | exports.default = nhats; 12 | 13 | var _util = require('./util'); 14 | 15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 16 | 17 | function nhats() { 18 | return { 19 | 20 | fetch: function fetch() { 21 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 22 | return new _promise2.default(function (resolve, reject) { 23 | return (0, _util.sendRequest)('ssd-api.jpl.nasa.gov', '/nhats.api', options, resolve, reject, _util.handleResult, true); 24 | }); 25 | } 26 | 27 | }; 28 | } 29 | module.exports = exports['default']; -------------------------------------------------------------------------------- /lib/patents.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _promise = require('babel-runtime/core-js/promise'); 8 | 9 | var _promise2 = _interopRequireDefault(_promise); 10 | 11 | exports.default = patents; 12 | 13 | var _util = require('./util'); 14 | 15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 16 | 17 | function patents() { 18 | return { 19 | 20 | fetch: function fetch() { 21 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 22 | return new _promise2.default(function (resolve, reject) { 23 | return (0, _util.sendRequest)('api.nasa.gov', '/patents/content', options, resolve, reject, _util.handleResult); 24 | }); 25 | } 26 | 27 | }; 28 | } 29 | module.exports = exports['default']; -------------------------------------------------------------------------------- /lib/scout.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _promise = require('babel-runtime/core-js/promise'); 8 | 9 | var _promise2 = _interopRequireDefault(_promise); 10 | 11 | exports.default = scout; 12 | 13 | var _util = require('./util'); 14 | 15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 16 | 17 | function scout() { 18 | return { 19 | 20 | fetch: function fetch() { 21 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 22 | return new _promise2.default(function (resolve, reject) { 23 | return (0, _util.sendRequest)('ssd-api.jpl.nasa.gov', '/scout.api', options, resolve, reject, _util.handleResult, true); 24 | }); 25 | } 26 | 27 | }; 28 | } 29 | module.exports = exports['default']; -------------------------------------------------------------------------------- /lib/sentry.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _promise = require('babel-runtime/core-js/promise'); 8 | 9 | var _promise2 = _interopRequireDefault(_promise); 10 | 11 | exports.default = sentry; 12 | 13 | var _util = require('./util'); 14 | 15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 16 | 17 | function sentry() { 18 | return { 19 | 20 | fetch: function fetch() { 21 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 22 | return new _promise2.default(function (resolve, reject) { 23 | return (0, _util.sendRequest)('ssd-api.jpl.nasa.gov', '/sentry.api', options, resolve, reject, _util.handleResult, true); 24 | }); 25 | } 26 | 27 | }; 28 | } 29 | module.exports = exports['default']; -------------------------------------------------------------------------------- /lib/sounds.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _promise = require('babel-runtime/core-js/promise'); 8 | 9 | var _promise2 = _interopRequireDefault(_promise); 10 | 11 | exports.default = sounds; 12 | 13 | var _util = require('./util'); 14 | 15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 16 | 17 | function sounds() { 18 | return { 19 | 20 | fetch: function fetch() { 21 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 22 | return new _promise2.default(function (resolve, reject) { 23 | return (0, _util.sendRequest)('api.nasa.gov', '/planetary/sounds', options, resolve, reject, _util.handleResult); 24 | }); 25 | } 26 | 27 | }; 28 | } 29 | module.exports = exports['default']; -------------------------------------------------------------------------------- /lib/util.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.validateDateTime = exports.validateDate = exports.sendRequest = exports.handleResult = undefined; 7 | 8 | var _https = require('https'); 9 | 10 | var _https2 = _interopRequireDefault(_https); 11 | 12 | var _config = require('./config'); 13 | 14 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 15 | 16 | var handleResult = function handleResult(resolve, reject, err, data) { 17 | if (err) return reject(err); 18 | return data ? resolve(data) : reject(new Error('No data found')); 19 | }; 20 | 21 | var sendRequest = function sendRequest(baseurl, endpoint) { 22 | var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 23 | var resolve = arguments[3]; 24 | var reject = arguments[4]; 25 | var cb = arguments[5]; 26 | var noKey = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false; 27 | 28 | var url = endpoint + '?'; 29 | if (options) { 30 | for (var key in options) { 31 | if (options.hasOwnProperty(key)) { 32 | var validKey = typeof options[key] === 'string' ? options[key].replace(/\s/g, '%20') : options[key]; 33 | url = '' + url + key + '=' + validKey + '&'; 34 | } 35 | } 36 | } 37 | if (_config.apiKey && !noKey) url = url + 'api_key=' + _config.apiKey; 38 | if (url[url.length - 1] === '&') url = url.substr(0, url.length - 1); 39 | 40 | var params = { 41 | host: baseurl, 42 | path: url, 43 | method: 'GET' 44 | }; 45 | 46 | var req = _https2.default.request(params, function (res) { 47 | if (res.statusCode < 200 || res.statusCode >= 300) { 48 | return cb(resolve, reject, new Error('statusCode=' + res.statusCode)); 49 | } 50 | var body = ''; 51 | res.on('data', function (c) { 52 | body += c.toString(); 53 | }); 54 | res.on('end', function () { 55 | return cb(resolve, reject, null, JSON.parse(body)); 56 | }); 57 | return undefined; 58 | }); 59 | req.on('error', function (err) { 60 | return cb(resolve, reject, new Error(err)); 61 | }); 62 | req.end(); 63 | }; 64 | 65 | var validateDate = function validateDate(date) { 66 | if (!date || typeof date !== 'string') return false; 67 | return date.match(/^\d{4}-\d{2}-\d{2}$/) !== null; 68 | }; 69 | 70 | var validateDateTime = function validateDateTime(date) { 71 | if (!date || typeof date !== 'string') return false; 72 | return date.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/) !== null; 73 | }; 74 | 75 | exports.handleResult = handleResult; 76 | exports.sendRequest = sendRequest; 77 | exports.validateDate = validateDate; 78 | exports.validateDateTime = validateDateTime; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nasa-sdk", 3 | "version": "1.1.11", 4 | "description": "SDK for NASA API", 5 | "author": "AJ Funk ", 6 | "main": "lib/index.js", 7 | "engines": { 8 | "node": ">=5.0", 9 | "npm": ">=3.3" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/AJFunk/nasa-sdk.git" 14 | }, 15 | "license": "MIT", 16 | "scripts": { 17 | "test": "export TEST_PATH=lib && mocha --timeout 8000 tests/* --compilers js:babel-register --require ./tests/helper.js --recursive", 18 | "test-source": "export TEST_PATH=src && mocha --timeout 8000 tests/* --compilers js:babel-register --require ./tests/helper.js --recursive", 19 | "start": "babel-node ./src/index.js", 20 | "lint": "eslint --ext .js ./", 21 | "build": "npm run lint && babel src -d lib", 22 | "flow": "flow" 23 | }, 24 | "devDependencies": { 25 | "app-module-path": "^1.0.6", 26 | "babel-cli": "^6.7.5", 27 | "babel-eslint": "^6.0.2", 28 | "babel-plugin-add-module-exports": "^0.1.2", 29 | "babel-plugin-transform-flow-strip-types": "^6.7.0", 30 | "babel-plugin-transform-runtime": "^6.23.0", 31 | "babel-preset-es2015": "^6.6.0", 32 | "babel-preset-stage-2": "^6.5.0", 33 | "babel-register": "^6.7.2", 34 | "chai": "^3.5.0", 35 | "eslint": "^2.7.0", 36 | "eslint-config-airbnb": "^7.0.0", 37 | "eslint-plugin-babel": "^3.2.0", 38 | "eslint-plugin-flow-vars": "^0.5.0", 39 | "eslint-plugin-flowtype": "^2.4.0", 40 | "flow-bin": "^0.44.0", 41 | "mocha": "^2.4.5" 42 | }, 43 | "dependencies": { 44 | "babel-runtime": "^6.23.0" 45 | }, 46 | "bugs": { 47 | "url": "https://github.com/AJFunk/nasa-sdk/issues" 48 | }, 49 | "homepage": "https://github.com/AJFunk/nasa-sdk#readme", 50 | "directories": { 51 | "test": "tests" 52 | }, 53 | "keywords": [ 54 | "nasa" 55 | ] 56 | } 57 | -------------------------------------------------------------------------------- /src/apod.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import { 3 | handleResult, 4 | sendRequest, 5 | validateDate, 6 | } from './util'; 7 | 8 | export default function apod(): Object { 9 | return { 10 | 11 | fetch: (options: Object = {}): Promise => 12 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => { 13 | if (options.hasOwnProperty('date') && !validateDate(options.date)) { 14 | return reject(new Error('date must be in "YYYY-MM-DD" format')); 15 | } 16 | return sendRequest( 17 | 'api.nasa.gov', 18 | '/planetary/apod', 19 | options, 20 | resolve, 21 | reject, 22 | handleResult 23 | ); 24 | }), 25 | 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /src/cad.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import { 3 | handleResult, 4 | sendRequest, 5 | validateDate, 6 | validateDateTime, 7 | } from './util'; 8 | 9 | export default function cad(): Object { 10 | function validateClass(className: String): boolean { 11 | const validClasses = [ 12 | 'IEO', 'ATE', 'APO', 'AMO', 'MCA', 'IMB', 'MBA', 'OMB', 'TJN', 'CEN', 'TNO', 13 | 'PAA', 'HYA', 'HYP', 'PAR', 'COM', 'JFC', 'HTC', 'ETc', 'CTc', 'JFc', 14 | ]; 15 | return validClasses.indexOf(className) === -1; 16 | } 17 | 18 | function validateBody(body: String): boolean { 19 | const validBodies = [ 20 | 'merc', 'venus', 'earth', 'mars', 'juptr', 'satrn', 'urnus', 'neptn', 'pluto', 'moon', 21 | ]; 22 | return validBodies.indexOf(body.toLowerCase()) === -1; 23 | } 24 | 25 | 26 | return { 27 | 28 | fetch: (options: Object = {}): Promise => 29 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => { 30 | const optionOverrides = {}; 31 | if (options.hasOwnProperty('date-min')) { 32 | if (!validateDate(options['date-min']) && !validateDateTime(options['date-min'])) { 33 | if (options['date-min'] !== 'now') { 34 | return reject(new Error('date-min is not in a valid format.')); 35 | } 36 | } 37 | } 38 | if (options.hasOwnProperty('date-max')) { 39 | if (!validateDate(options['date-max']) && !validateDateTime(options['date-max'])) { 40 | if (options['date-max'].match(/^[+]\d+$/)) { 41 | optionOverrides['date-max'] = options['date-max'].replace(/[+]/, '%2B'); 42 | } else if (options['date-max'] !== 'now') { 43 | return reject(new Error('date-max is not in a valid format.')); 44 | } 45 | } 46 | } 47 | if (options.hasOwnProperty('class')) { 48 | if (!validateClass(options.class)) return reject(new Error('Invalid class value')); 49 | } 50 | if (options.hasOwnProperty('body')) { 51 | if (!validateBody(options.body)) return reject(new Error('Invalid body value')); 52 | } 53 | return sendRequest( 54 | 'ssd-api.jpl.nasa.gov', 55 | '/cad.api', 56 | Object.assign({}, options, optionOverrides), 57 | resolve, 58 | reject, 59 | handleResult, 60 | true 61 | ); 62 | }), 63 | 64 | }; 65 | } 66 | -------------------------------------------------------------------------------- /src/config.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | let apiKey = process.env.NASA_API_KEY; 3 | const setNasaApiKey = (key: string): null => { 4 | apiKey = key; 5 | return null; 6 | }; 7 | 8 | export { 9 | apiKey, 10 | setNasaApiKey, 11 | }; 12 | -------------------------------------------------------------------------------- /src/earth.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import { 3 | handleResult, 4 | sendRequest, 5 | validateDate, 6 | } from './util'; 7 | const baseurl = 'api.nasa.gov'; 8 | const endpointbase = '/planetary/earth/'; 9 | 10 | export default function earth(): Object { 11 | return { 12 | 13 | imagery: (options: Object = {}): Promise => 14 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => { 15 | if (options.hasOwnProperty('date') && !validateDate(options.date)) { 16 | return reject(new Error('date must be in "YYYY-MM-DD" format')); 17 | } 18 | return sendRequest( 19 | baseurl, 20 | `${endpointbase}imagery`, 21 | options, 22 | resolve, 23 | reject, 24 | handleResult 25 | ); 26 | }), 27 | 28 | assets: (options: Object = {}): Promise => 29 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => { 30 | if (options.hasOwnProperty('begin') && !validateDate(options.begin)) { 31 | return reject(new Error('date must be in "YYYY-MM-DD" format')); 32 | } 33 | if (options.hasOwnProperty('end') && !validateDate(options.end)) { 34 | return reject(new Error('date must be in "YYYY-MM-DD" format')); 35 | } 36 | return sendRequest( 37 | baseurl, 38 | `${endpointbase}assets`, 39 | options, 40 | resolve, 41 | reject, 42 | handleResult 43 | ); 44 | }), 45 | 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /src/eonet.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import { 3 | handleResult, 4 | sendRequest, 5 | } from './util'; 6 | const baseurl = 'eonet.sci.gsfc.nasa.gov'; 7 | const endpointbase = '/api/v2.1/'; 8 | 9 | export default function eonet(): Object { 10 | return { 11 | 12 | events: (options: Object = {}): Promise => 13 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => { 14 | let endpoint = `${endpointbase}events`; 15 | if (options.hasOwnProperty('eventId')) endpoint = `${endpoint}/${options.eventId}`; 16 | return sendRequest( 17 | baseurl, 18 | endpoint, 19 | options, 20 | resolve, 21 | reject, 22 | handleResult 23 | ); 24 | }), 25 | 26 | categories: (options: Object = {}): Promise => 27 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => { 28 | let endpoint = `${endpointbase}categories`; 29 | if (options.hasOwnProperty('categoryId')) endpoint = `${endpoint}/${options.categoryId}`; 30 | return sendRequest( 31 | baseurl, 32 | endpoint, 33 | options, 34 | resolve, 35 | reject, 36 | handleResult 37 | ); 38 | }), 39 | 40 | sources: (): Promise => 41 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => 42 | sendRequest( 43 | baseurl, 44 | `${endpointbase}sources`, 45 | {}, 46 | resolve, 47 | reject, 48 | handleResult 49 | ) 50 | ), 51 | 52 | layers: (options: Object = {}): Promise => 53 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => { 54 | let endpoint = `${endpointbase}layers`; 55 | if (options.hasOwnProperty('categoryId')) endpoint = `${endpoint}/${options.categoryId}`; 56 | return sendRequest( 57 | baseurl, 58 | endpoint, 59 | {}, 60 | resolve, 61 | reject, 62 | handleResult 63 | ); 64 | }), 65 | 66 | }; 67 | } 68 | -------------------------------------------------------------------------------- /src/epic.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import { 3 | handleResult, 4 | sendRequest, 5 | validateDate, 6 | } from './util'; 7 | const baseurl = 'api.nasa.gov'; 8 | const endpointbase = '/EPIC/api/'; 9 | 10 | export default function epic(): Object { 11 | function validateType(type: string): string { 12 | const validTypes = ['natural', 'enhanced']; 13 | const i = validTypes.indexOf(type.toLowerCase()); 14 | return i === -1 ? '' : validTypes[i]; 15 | } 16 | 17 | return { 18 | 19 | fetch: (type: string): Promise => 20 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => { 21 | if (!type) return reject(new Error('Image quality type is required')); 22 | const validType = validateType(type); 23 | if (!validType) return reject(new Error('Invalid image quality type')); 24 | return sendRequest( 25 | baseurl, 26 | `${endpointbase}${validType}`, 27 | {}, 28 | resolve, 29 | reject, 30 | handleResult 31 | ); 32 | }), 33 | 34 | date: (type: string, date: string): Promise => 35 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => { 36 | if (!type) return reject(new Error('Image quality type is required')); 37 | const validType = validateType(type); 38 | if (!validType) return reject(new Error('Invalid image quality type')); 39 | if (!date) return reject(new Error('date is required')); 40 | if (!validateDate(date)) return reject(new Error('date must be in "YYYY-MM-DD" format')); 41 | return sendRequest( 42 | baseurl, 43 | `${endpointbase}${type}/date/${date}`, 44 | {}, 45 | resolve, 46 | reject, 47 | handleResult 48 | ); 49 | }), 50 | 51 | all: (type: string): Promise => 52 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => { 53 | if (!type) return reject(new Error('Image quality type is required')); 54 | const validType = validateType(type); 55 | if (!validType) return reject(new Error('Invalid image quality type')); 56 | return sendRequest( 57 | baseurl, 58 | `${endpointbase}${type}/all`, 59 | {}, 60 | resolve, 61 | reject, 62 | handleResult 63 | ); 64 | }), 65 | 66 | available: (type: string): Promise => 67 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => { 68 | if (!type) return reject(new Error('Image quality type is required')); 69 | const validType = validateType(type); 70 | if (!validType) return reject(new Error('Invalid image quality type')); 71 | return sendRequest( 72 | baseurl, 73 | `${endpointbase}${type}/available`, 74 | {}, 75 | resolve, 76 | reject, 77 | handleResult 78 | ); 79 | }), 80 | 81 | }; 82 | } 83 | -------------------------------------------------------------------------------- /src/fireballs.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import { 3 | handleResult, 4 | sendRequest, 5 | validateDate, 6 | validateDateTime, 7 | } from './util'; 8 | 9 | export default function fireballs(): Object { 10 | return { 11 | 12 | fetch: (options: Object = {}): Promise => 13 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => { 14 | if (options.hasOwnProperty('date-min')) { 15 | if (!validateDate(options['date-min']) && !validateDateTime(options['date-min'])) { 16 | return reject(new Error('date-min is not in a valid format.')); 17 | } 18 | } 19 | if (options.hasOwnProperty('date-max')) { 20 | if (!validateDate(options['date-max']) && !validateDateTime(options['date-max'])) { 21 | return reject(new Error('date-max is not in a valid format.')); 22 | } 23 | } 24 | return sendRequest( 25 | 'ssd-api.jpl.nasa.gov', 26 | '/fireball.api', 27 | options, 28 | resolve, 29 | reject, 30 | handleResult, 31 | true 32 | ); 33 | }), 34 | 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /src/images.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import { 3 | handleResult, 4 | sendRequest, 5 | } from './util'; 6 | 7 | export default function images(): Object { 8 | const baseurl = 'images-api.nasa.gov'; 9 | 10 | function validateMediaType(mediaType: string): boolean { 11 | if (!mediaType || typeof mediaType !== 'string') return false; 12 | return mediaType.match(/^image$|^audio$|^image,audio$|^audio,image$/) !== null; 13 | } 14 | 15 | function validateYear(year: string): boolean { 16 | if (!year || typeof year !== 'string') return false; 17 | return year.match(/^\d{4}$/) !== null; 18 | } 19 | 20 | return { 21 | 22 | search: (options: Object = {}): Promise => 23 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => { 24 | if (!Object.keys(options).length) { 25 | return reject(new Error('Atleast one search param is required')); 26 | } 27 | if (options.hasOwnProperty('media_type') && !validateMediaType(options.media_type)) { 28 | return reject( 29 | new Error('media_type values must match image||audio||image,audio||audio,image') 30 | ); 31 | } 32 | if (options.hasOwnProperty('year_start') && !validateYear(options.year_start)) { 33 | return reject(new Error('year_start must be in "YYYY" format')); 34 | } 35 | if (options.hasOwnProperty('year_end') && !validateYear(options.year_end)) { 36 | return reject(new Error('year_end must be in "YYYY" format')); 37 | } 38 | return sendRequest( 39 | baseurl, 40 | '/search', 41 | options, 42 | resolve, 43 | reject, 44 | handleResult, 45 | true 46 | ); 47 | }), 48 | 49 | asset: (nasaId: string): Promise => 50 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => { 51 | if (!nasaId) return reject(new Error('nasaId is required')); 52 | return sendRequest( 53 | baseurl, 54 | `/asset/${nasaId}`, 55 | {}, 56 | resolve, 57 | reject, 58 | handleResult, 59 | true 60 | ); 61 | }), 62 | 63 | metadata: (nasaId: string): Promise => 64 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => { 65 | if (!nasaId) return reject(new Error('nasaId is required')); 66 | return sendRequest( 67 | baseurl, 68 | `/metadata/${nasaId}`, 69 | {}, 70 | resolve, 71 | reject, 72 | handleResult, 73 | true 74 | ); 75 | }), 76 | 77 | captions: (nasaId: string): Promise => 78 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => { 79 | if (!nasaId) return reject(new Error('nasaId is required')); 80 | return sendRequest( 81 | baseurl, 82 | `/captions/${nasaId}`, 83 | {}, 84 | resolve, 85 | reject, 86 | handleResult, 87 | true, 88 | ); 89 | }), 90 | 91 | }; 92 | } 93 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { setNasaApiKey } from './config'; 2 | 3 | const APOD = require('./apod')(); 4 | const CAD = require('./cad')(); 5 | const Earth = require('./earth')(); 6 | const EONET = require('./eonet')(); 7 | const EPIC = require('./epic')(); 8 | const Fireballs = require('./fireballs')(); 9 | const Images = require('./images')(); 10 | const MarsPhotos = require('./mars-photos')(); 11 | const NEO = require('./neo')(); 12 | const NHATS = require('./nhats')(); 13 | const Patents = require('./patents')(); 14 | const Scout = require('./scout')(); 15 | const Sentry = require('./sentry')(); 16 | const Sounds = require('./sounds')(); 17 | 18 | export { 19 | APOD, 20 | CAD, 21 | Earth, 22 | EONET, 23 | EPIC, 24 | Fireballs, 25 | Images, 26 | MarsPhotos, 27 | NEO, 28 | NHATS, 29 | Patents, 30 | Scout, 31 | Sentry, 32 | Sounds, 33 | setNasaApiKey, 34 | }; 35 | -------------------------------------------------------------------------------- /src/mars-photos.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import { 3 | handleResult, 4 | sendRequest, 5 | validateDate, 6 | } from './util'; 7 | const baseurl = 'api.nasa.gov'; 8 | const endpointbase = '/mars-photos/api/v1/'; 9 | 10 | export default function marsPhotos(): Object { 11 | function validateRover(rover: string): string { 12 | const validRovers = ['curiosity', 'opportunity', 'spirit', 'perseverance']; 13 | const i = validRovers.indexOf(rover.toLowerCase()); 14 | return i === -1 ? '' : validRovers[i]; 15 | } 16 | 17 | function validateCamera(rover: string, camera: string): string { 18 | const validCameras = { 19 | curiosity: ['fhaz', 'rhaz', 'mast', 'chemcam', 'mahli', 'mardi', 'navcam'], 20 | opportunity: ['fhaz', 'rhaz', 'navcam', 'pancam', 'minites'], 21 | spirit: ['fhaz', 'rhaz', 'navcam', 'pancam', 'minites'], 22 | perseverance: ['edl_rucam', 'edl_rdcam', 'edl_ddcam', 'edl_pucam1', 'edl_pucam2', 23 | 'navcam_left', 'navcam_right', 'mcz_right', 'mcz_left', 'front_hazcam_left_a', 24 | 'front_hazcam_right_a', 'rear_hazcam_left', 'rear_hazcam_right'], 25 | }; 26 | const i = validCameras[rover].indexOf(camera.toLowerCase()); 27 | return i === -1 ? '' : validCameras[rover][i]; 28 | } 29 | 30 | return { 31 | 32 | fetch: (rover: string, options: Object = {}): Promise => 33 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => { 34 | if (!rover) return reject(new Error('Rover name is required')); 35 | const validRover = validateRover(rover); 36 | if (!validRover) return reject(new Error('Invalid rover name')); 37 | let validCamera; 38 | if (options.hasOwnProperty('camera')) { 39 | validCamera = validateCamera(validRover, options.camera); 40 | if (!validCamera) return reject(new Error('Invalid camera name')); 41 | } 42 | if (!options.hasOwnProperty('sol') && !options.hasOwnProperty('earth_date')) { 43 | return reject(new Error('You must provide either earth_date or sol')); 44 | } 45 | if (options.hasOwnProperty('earth_date') && !validateDate(options.earth_date)) { 46 | return reject(new Error('earth_date must be in "YYYY-MM-DD" format')); 47 | } 48 | return sendRequest( 49 | baseurl, 50 | `${endpointbase}rovers/${validRover}/photos`, 51 | Object.assign({}, options, { camera: validCamera }), 52 | resolve, 53 | reject, 54 | handleResult 55 | ); 56 | }), 57 | 58 | manifest: (rover: string): Promise => 59 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => { 60 | if (!rover) return reject(new Error('Rover name is required')); 61 | const validRover = validateRover(rover); 62 | if (!validRover) return reject(new Error('Invalid rover name')); 63 | return sendRequest( 64 | baseurl, 65 | `${endpointbase}manifests/${validRover}`, 66 | {}, 67 | resolve, 68 | reject, 69 | handleResult 70 | ); 71 | }), 72 | 73 | }; 74 | } 75 | -------------------------------------------------------------------------------- /src/neo.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import { 3 | handleResult, 4 | sendRequest, 5 | validateDate, 6 | } from './util'; 7 | const baseurl = 'api.nasa.gov'; 8 | const endpointbase = '/neo/rest/v1/'; 9 | 10 | export default function neo(): Object { 11 | return { 12 | 13 | feed: (options: Object = {}): Promise => 14 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => { 15 | if (options.hasOwnProperty('start_date') && !validateDate(options.start_date)) { 16 | return reject(new Error('start_date must be in "YYYY-MM-DD" format')); 17 | } 18 | if (options.hasOwnProperty('end_date') && !validateDate(options.end_date)) { 19 | return reject(new Error('end_date must be in "YYYY-MM-DD" format')); 20 | } 21 | return sendRequest( 22 | baseurl, 23 | `${endpointbase}feed`, 24 | options, 25 | resolve, 26 | reject, 27 | handleResult 28 | ); 29 | }), 30 | 31 | feedToday: (options: Object = {}): Promise => 32 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => 33 | sendRequest( 34 | baseurl, 35 | `${endpointbase}feed/today`, 36 | options, 37 | resolve, 38 | reject, 39 | handleResult 40 | ) 41 | ), 42 | 43 | fetch: (asteroidId: string): Promise => 44 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => { 45 | if (!asteroidId) return reject(new Error('asteroidId is required')); 46 | return sendRequest( 47 | baseurl, 48 | `${endpointbase}neo/${asteroidId}`, 49 | {}, 50 | resolve, 51 | reject, 52 | handleResult 53 | ); 54 | }), 55 | 56 | browse: (options: Object = {}): Promise => 57 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => 58 | sendRequest( 59 | baseurl, 60 | `${endpointbase}neo/browse`, 61 | options, 62 | resolve, 63 | reject, 64 | handleResult 65 | ) 66 | ), 67 | 68 | stats: (): Promise => 69 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => 70 | sendRequest( 71 | baseurl, 72 | `${endpointbase}stats`, 73 | {}, 74 | resolve, 75 | reject, 76 | handleResult 77 | ) 78 | ), 79 | 80 | }; 81 | } 82 | -------------------------------------------------------------------------------- /src/nhats.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import { 3 | handleResult, 4 | sendRequest, 5 | } from './util'; 6 | 7 | export default function nhats(): Object { 8 | return { 9 | 10 | fetch: (options: Object = {}): Promise => 11 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => 12 | sendRequest( 13 | 'ssd-api.jpl.nasa.gov', 14 | '/nhats.api', 15 | options, 16 | resolve, 17 | reject, 18 | handleResult, 19 | true 20 | ) 21 | ), 22 | 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /src/patents.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import { 3 | handleResult, 4 | sendRequest, 5 | } from './util'; 6 | 7 | export default function patents(): Object { 8 | return { 9 | 10 | fetch: (options: Object = {}): Promise => 11 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => 12 | sendRequest( 13 | 'api.nasa.gov', 14 | '/patents/content', 15 | options, 16 | resolve, 17 | reject, 18 | handleResult 19 | ) 20 | ), 21 | 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /src/scout.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import { 3 | handleResult, 4 | sendRequest, 5 | } from './util'; 6 | 7 | export default function scout(): Object { 8 | return { 9 | 10 | fetch: (options: Object = {}): Promise => 11 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => 12 | sendRequest( 13 | 'ssd-api.jpl.nasa.gov', 14 | '/scout.api', 15 | options, 16 | resolve, 17 | reject, 18 | handleResult, 19 | true 20 | ) 21 | ), 22 | 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /src/sentry.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import { 3 | handleResult, 4 | sendRequest, 5 | } from './util'; 6 | 7 | export default function sentry(): Object { 8 | return { 9 | 10 | fetch: (options: Object = {}): Promise => 11 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => 12 | sendRequest( 13 | 'ssd-api.jpl.nasa.gov', 14 | '/sentry.api', 15 | options, 16 | resolve, 17 | reject, 18 | handleResult, 19 | true 20 | ) 21 | ), 22 | 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /src/sounds.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import { 3 | handleResult, 4 | sendRequest, 5 | } from './util'; 6 | 7 | export default function sounds(): Object { 8 | return { 9 | 10 | fetch: (options: Object = {}): Promise => 11 | new Promise((resolve: (data: Object) => void, reject: (reason: Error) => void): mixed => 12 | sendRequest( 13 | 'api.nasa.gov', 14 | '/planetary/sounds', 15 | options, 16 | resolve, 17 | reject, 18 | handleResult 19 | ) 20 | ), 21 | 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /src/util.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import https from 'https'; 3 | import { apiKey } from './config'; 4 | 5 | const handleResult = (resolve: (data: Object) => void, 6 | reject: (reason: Error) => void, 7 | err: Error | null, 8 | data?: Object): mixed => { 9 | if (err) return reject(err); 10 | return data ? resolve(data) : reject(new Error('No data found')); 11 | }; 12 | 13 | const sendRequest = (baseurl: string, 14 | endpoint: string, 15 | options: Object = {}, 16 | resolve: (data: Object) => void, 17 | reject: (reason: Error) => void, 18 | cb: Function, 19 | noKey?: boolean = false): void => { 20 | let url = `${endpoint}?`; 21 | if (options) { 22 | for (const key in options) { 23 | if (options.hasOwnProperty(key)) { 24 | const validKey = typeof options[key] === 'string' ? 25 | options[key].replace(/\s/g, '%20') : options[key]; 26 | url = `${url}${key}=${validKey}&`; 27 | } 28 | } 29 | } 30 | if (apiKey && !noKey) url = `${url}api_key=${apiKey}`; 31 | if (url[url.length - 1] === '&') url = url.substr(0, url.length - 1); 32 | 33 | const params = { 34 | host: baseurl, 35 | path: url, 36 | method: 'GET', 37 | }; 38 | 39 | const req = https.request(params, (res: any): void => { 40 | if (res.statusCode < 200 || res.statusCode >= 300) { 41 | return cb(resolve, reject, new Error(`statusCode=${res.statusCode}`)); 42 | } 43 | let body = ''; 44 | res.on('data', (c: Object): void => { 45 | body += c.toString(); 46 | }); 47 | res.on('end', (): Object => 48 | cb(resolve, reject, null, JSON.parse(body))); 49 | return undefined; 50 | }); 51 | req.on('error', (err: Object): Object => cb(resolve, reject, new Error(err))); 52 | req.end(); 53 | }; 54 | 55 | const validateDate = (date: string): boolean => { 56 | if (!date || typeof date !== 'string') return false; 57 | return date.match(/^\d{4}-\d{2}-\d{2}$/) !== null; 58 | }; 59 | 60 | const validateDateTime = (date: string): boolean => { 61 | if (!date || typeof date !== 'string') return false; 62 | return date.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/) !== null; 63 | }; 64 | 65 | export { 66 | handleResult, 67 | sendRequest, 68 | validateDate, 69 | validateDateTime, 70 | }; 71 | -------------------------------------------------------------------------------- /tests/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "flow-vars/define-flow-type": 0, 4 | "flow-vars/use-flow-type": 0, 5 | "flowtype/require-parameter-type": 0, 6 | "flowtype/require-return-type": 0, 7 | "flowtype/space-after-type-colon": 0, 8 | "flowtype/space-before-type-colon": 0, 9 | "flowtype/type-id-match": 0 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/apod.spec.js: -------------------------------------------------------------------------------- 1 | import { APOD } from 'index'; 2 | 3 | describe('APOD.fetch()', () => { 4 | it('returns object', () => 5 | APOD.fetch().then(data => expect(data).to.be.instanceof(Object)) 6 | ); 7 | 8 | it('returns object', () => 9 | APOD.fetch({ date: '2016-06-01' }).then(data => expect(data).to.be.instanceof(Object)) 10 | ); 11 | 12 | it('returns object', () => 13 | APOD.fetch({ date: '2016-0' }).catch(err => expect(err).to.be.an('error')) 14 | ); 15 | 16 | it('returns specific APOD object', () => { 17 | const apodObj = { 18 | date: '2016-06-01', 19 | explanation: 'What star created this huge expanding puffball? Featured here is the first ' + 20 | 'expansion movie ever created for Tycho\'s supernova remnant, the result of a stellar ' + 21 | 'explosion first recorded over 400 years ago by the famous astronomer Tycho Brahe. The ' + 22 | '2-second video is a time-lapse composite of X-ray images taken by the orbiting Chandra ' + 23 | 'X-ray Observatory between the years 2000 and 2015, added to a stock optical frame. The ' + 24 | 'expanding gas cloud is extremely hot, while slightly different expansion speeds have ' + 25 | 'given the cloud a puffy appearance. Although the star that created SN 1572, is likely ' + 26 | 'completely gone, a star dubbed Tycho G, too dim to be discerned here, is thought to be a ' + 27 | 'companion. Finding progenitor remnants of Tycho\'s supernova is particularly important ' + 28 | 'because the supernova is of Type Ia, an important rung in the distance ladder that ' + 29 | 'calibrates the scale of the visible universe. The peak brightness of Type Ia supernovas ' + 30 | 'is thought to be well understood, making them quite valuable in exploring the ' + 31 | 'relationship between faintness and farness in the distant universe.', 32 | media_type: 'video', 33 | service_version: 'v1', 34 | title: 'Tycho\'s Supernova Remnant Expands', 35 | url: 'https://www.youtube.com/embed/jOmb-STnOg4?rel=0', 36 | }; 37 | return APOD.fetch({ date: '2016-06-01' }).then(data => assert.deepEqual(data, apodObj)); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /tests/cad.spec.js: -------------------------------------------------------------------------------- 1 | import { CAD } from 'index'; 2 | 3 | describe('CAD.fetch()', () => { 4 | it('returns object', () => 5 | CAD.fetch().then(data => expect(data).to.be.instanceof(Object)) 6 | ); 7 | 8 | it('returns object', () => 9 | CAD.fetch({ 10 | 'date-min': '2015-01-05', 11 | 'date-max': '+20', 12 | }).then(data => expect(data).to.be.instanceof(Object)) 13 | ); 14 | 15 | it('returns object', () => 16 | CAD.fetch({ 17 | 'date-min': 'now', 18 | 'date-max': '+20', 19 | }).then(data => expect(data).to.be.instanceof(Object)) 20 | ); 21 | 22 | it('returns error message', () => 23 | CAD.fetch({ 'date-min': '1234' }).catch(err => expect(err).to.be.an('error')) 24 | ); 25 | 26 | it('returns error message', () => 27 | CAD.fetch({ 28 | 'date-min': '2015-01-05', 29 | 'date-max': '2015-01-08T12', 30 | }).catch(err => expect(err).to.be.an('error')) 31 | ); 32 | }); 33 | -------------------------------------------------------------------------------- /tests/config.spec.js: -------------------------------------------------------------------------------- 1 | import { apiKey } from 'config'; 2 | import { setNasaApiKey } from 'index'; 3 | 4 | describe('setNasaApiKey()', () => { 5 | it('sets apiKey', () => { 6 | const oldKey = apiKey; 7 | setNasaApiKey('1234'); 8 | expect(apiKey).to.be.equal('1234'); 9 | return setNasaApiKey(oldKey); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /tests/earth.spec.js: -------------------------------------------------------------------------------- 1 | import { Earth } from 'index'; 2 | 3 | describe('Earth.imagery()', () => { 4 | it('returns object', () => 5 | Earth.imagery().then(data => expect(data).to.be.instanceof(Object)) 6 | ); 7 | 8 | it('returns object', () => 9 | Earth.imagery({ 10 | lon: 100.75, 11 | lat: 1.5, 12 | date: '2014-02-01', 13 | cloud_score: true, 14 | }).then(data => expect(data).to.be.instanceof(Object)) 15 | ); 16 | }); 17 | 18 | describe('Earth.assets()', () => { 19 | it('returns object', () => 20 | Earth.assets().then(data => expect(data).to.be.instanceof(Object)) 21 | ); 22 | 23 | it('returns object', () => 24 | Earth.assets({ 25 | lon: 100.75, 26 | lat: 1.5, 27 | begin: '2014-02-01', 28 | }).then(data => expect(data).to.be.instanceof(Object)) 29 | ); 30 | 31 | it('returns a specific Earth Asset object', () => { 32 | const earthAssetObj = { 33 | count: 66, 34 | results: [ 35 | { 36 | date: '2014-02-04T03:30:01', 37 | id: 'LC8_L1T_TOA/LC81270592014035LGN00', 38 | }, 39 | { 40 | date: '2014-02-20T03:29:47', 41 | id: 'LC8_L1T_TOA/LC81270592014051LGN00', 42 | }, 43 | { 44 | date: '2014-03-08T03:29:33', 45 | id: 'LC8_L1T_TOA/LC81270592014067LGN00', 46 | }, 47 | { 48 | date: '2014-03-24T03:29:20', 49 | id: 'LC8_L1T_TOA/LC81270592014083LGN00', 50 | }, 51 | { 52 | date: '2014-04-09T03:29:06', 53 | id: 'LC8_L1T_TOA/LC81270592014099LGN00', 54 | }, 55 | { 56 | date: '2014-04-25T03:28:50', 57 | id: 'LC8_L1T_TOA/LC81270592014115LGN00', 58 | }, 59 | { 60 | date: '2014-05-11T03:28:35', 61 | id: 'LC8_L1T_TOA/LC81270592014131LGN00', 62 | }, 63 | { 64 | date: '2014-05-27T03:28:32', 65 | id: 'LC8_L1T_TOA/LC81270592014147LGN00', 66 | }, 67 | { 68 | date: '2014-06-12T03:28:41', 69 | id: 'LC8_L1T_TOA/LC81270592014163LGN00', 70 | }, 71 | { 72 | date: '2014-06-28T03:28:43', 73 | id: 'LC8_L1T_TOA/LC81270592014179LGN00', 74 | }, 75 | { 76 | date: '2014-07-14T03:28:51', 77 | id: 'LC8_L1T_TOA/LC81270592014195LGN01', 78 | }, 79 | { 80 | date: '2014-07-30T03:28:56', 81 | id: 'LC8_L1T_TOA/LC81270592014211LGN00', 82 | }, 83 | { 84 | date: '2014-08-15T03:29:03', 85 | id: 'LC8_L1T_TOA/LC81270592014227LGN00', 86 | }, 87 | { 88 | date: '2014-08-31T03:29:05', 89 | id: 'LC8_L1T_TOA/LC81270592014243LGN00', 90 | }, 91 | { 92 | date: '2014-09-16T03:29:07', 93 | id: 'LC8_L1T_TOA/LC81270592014259LGN00', 94 | }, 95 | { 96 | date: '2014-10-02T03:29:09', 97 | id: 'LC8_L1T_TOA/LC81270592014275LGN00', 98 | }, 99 | { 100 | date: '2014-10-18T03:29:13', 101 | id: 'LC8_L1T_TOA/LC81270592014291LGN00', 102 | }, 103 | { 104 | date: '2014-11-03T03:29:11', 105 | id: 'LC8_L1T_TOA/LC81270592014307LGN00', 106 | }, 107 | { 108 | date: '2014-11-19T03:29:10', 109 | id: 'LC8_L1T_TOA/LC81270592014323LGN00', 110 | }, 111 | { 112 | date: '2014-12-05T03:29:09', 113 | id: 'LC8_L1T_TOA/LC81270592014339LGN00', 114 | }, 115 | { 116 | date: '2014-12-21T03:29:07', 117 | id: 'LC8_L1T_TOA/LC81270592014355LGN00', 118 | }, 119 | { 120 | date: '2015-01-06T03:29:02', 121 | id: 'LC8_L1T_TOA/LC81270592015006LGN00', 122 | }, 123 | { 124 | date: '2015-02-07T03:28:54', 125 | id: 'LC8_L1T_TOA/LC81270592015038LGN00', 126 | }, 127 | { 128 | date: '2015-02-23T03:28:48', 129 | id: 'LC8_L1T_TOA/LC81270592015054LGN00', 130 | }, 131 | { 132 | date: '2015-03-11T03:28:37', 133 | id: 'LC8_L1T_TOA/LC81270592015070LGN00', 134 | }, 135 | { 136 | date: '2015-03-27T03:28:29', 137 | id: 'LC8_L1T_TOA/LC81270592015086LGN00', 138 | }, 139 | { 140 | date: '2015-04-12T03:28:22', 141 | id: 'LC8_L1T_TOA/LC81270592015102LGN00', 142 | }, 143 | { 144 | date: '2015-04-28T03:28:16', 145 | id: 'LC8_L1T_TOA/LC81270592015118LGN00', 146 | }, 147 | { 148 | date: '2015-05-14T03:28:00', 149 | id: 'LC8_L1T_TOA/LC81270592015134LGN00', 150 | }, 151 | { 152 | date: '2015-05-30T03:28:04', 153 | id: 'LC8_L1T_TOA/LC81270592015150LGN00', 154 | }, 155 | { 156 | date: '2015-06-15T03:28:16', 157 | id: 'LC8_L1T_TOA/LC81270592015166LGN00', 158 | }, 159 | { 160 | date: '2015-07-01T03:28:23', 161 | id: 'LC8_L1T_TOA/LC81270592015182LGN00', 162 | }, 163 | { 164 | date: '2015-07-17T03:28:33', 165 | id: 'LC8_L1T_TOA/LC81270592015198LGN00', 166 | }, 167 | { 168 | date: '2015-08-02T03:28:36', 169 | id: 'LC8_L1T_TOA/LC81270592015214LGN00', 170 | }, 171 | { 172 | date: '2015-08-18T03:28:43', 173 | id: 'LC8_L1T_TOA/LC81270592015230LGN00', 174 | }, 175 | { 176 | date: '2015-09-03T03:28:48', 177 | id: 'LC8_L1T_TOA/LC81270592015246LGN00', 178 | }, 179 | { 180 | date: '2015-10-05T03:29:00', 181 | id: 'LC8_L1T_TOA/LC81270592015278LGN00', 182 | }, 183 | { 184 | date: '2015-10-21T03:29:03', 185 | id: 'LC8_L1T_TOA/LC81270592015294LGN00', 186 | }, 187 | { 188 | date: '2015-11-22T03:29:08', 189 | id: 'LC8_L1T_TOA/LC81270592015326LGN00', 190 | }, 191 | { 192 | date: '2015-12-08T03:29:07', 193 | id: 'LC8_L1T_TOA/LC81270592015342LGN00', 194 | }, 195 | { 196 | date: '2015-12-24T03:29:08', 197 | id: 'LC8_L1T_TOA/LC81270592015358LGN00', 198 | }, 199 | { 200 | date: '2016-01-09T03:29:03', 201 | id: 'LC8_L1T_TOA/LC81270592016009LGN00', 202 | }, 203 | { 204 | date: '2016-01-25T03:29:04', 205 | id: 'LC8_L1T_TOA/LC81270592016025LGN00', 206 | }, 207 | { 208 | date: '2016-02-10T03:28:59', 209 | id: 'LC8_L1T_TOA/LC81270592016041LGN00', 210 | }, 211 | { 212 | date: '2016-02-26T03:28:53', 213 | id: 'LC8_L1T_TOA/LC81270592016057LGN00', 214 | }, 215 | { 216 | date: '2016-03-13T03:28:50', 217 | id: 'LC8_L1T_TOA/LC81270592016073LGN00', 218 | }, 219 | { 220 | date: '2016-03-29T03:28:40', 221 | id: 'LC8_L1T_TOA/LC81270592016089LGN00', 222 | }, 223 | { 224 | date: '2016-04-14T03:28:35', 225 | id: 'LC8_L1T_TOA/LC81270592016105LGN00', 226 | }, 227 | { 228 | date: '2016-04-30T03:28:35', 229 | id: 'LC8_L1T_TOA/LC81270592016121LGN00', 230 | }, 231 | { 232 | date: '2016-06-01T03:28:39', 233 | id: 'LC8_L1T_TOA/LC81270592016153LGN00', 234 | }, 235 | { 236 | date: '2016-07-03T03:28:51', 237 | id: 'LC8_L1T_TOA/LC81270592016185LGN00', 238 | }, 239 | { 240 | date: '2016-07-19T03:28:58', 241 | id: 'LC8_L1T_TOA/LC81270592016201LGN00', 242 | }, 243 | { 244 | date: '2016-08-04T03:29:01', 245 | id: 'LC8_L1T_TOA/LC81270592016217LGN00', 246 | }, 247 | { 248 | date: '2016-08-20T03:29:06', 249 | id: 'LC8_L1T_TOA/LC81270592016233LGN00', 250 | }, 251 | { 252 | date: '2016-09-05T03:29:12', 253 | id: 'LC8_L1T_TOA/LC81270592016249LGN00', 254 | }, 255 | { 256 | date: '2016-09-21T03:29:13', 257 | id: 'LC8_L1T_TOA/LC81270592016265LGN00', 258 | }, 259 | { 260 | date: '2016-10-23T03:29:20', 261 | id: 'LC8_L1T_TOA/LC81270592016297LGN00', 262 | }, 263 | { 264 | date: '2016-11-08T03:29:19', 265 | id: 'LC8_L1T_TOA/LC81270592016313LGN00', 266 | }, 267 | { 268 | date: '2016-11-24T03:29:20', 269 | id: 'LC8_L1T_TOA/LC81270592016329LGN00', 270 | }, 271 | { 272 | date: '2016-12-10T03:29:17', 273 | id: 'LC8_L1T_TOA/LC81270592016345LGN00', 274 | }, 275 | { 276 | date: '2017-01-11T03:29:10', 277 | id: 'LC8_L1T_TOA/LC81270592017011LGN00', 278 | }, 279 | { 280 | date: '2017-01-27T03:29:04', 281 | id: 'LC8_L1T_TOA/LC81270592017027LGN00', 282 | }, 283 | { 284 | date: '2017-02-12T03:28:56', 285 | id: 'LC8_L1T_TOA/LC81270592017043LGN00', 286 | }, 287 | { 288 | date: '2017-02-28T03:28:51', 289 | id: 'LC8_L1T_TOA/LC81270592017059LGN00', 290 | }, 291 | { 292 | date: '2017-03-16T03:28:42', 293 | id: 'LC8_L1T_TOA/LC81270592017075LGN00', 294 | }, 295 | { 296 | date: '2017-04-01T03:28:34', 297 | id: 'LC8_L1T_TOA/LC81270592017091LGN00', 298 | }, 299 | ], 300 | }; 301 | return Earth.assets({ 302 | lon: 100.75, 303 | lat: 1.5, 304 | begin: '2014-02-01', 305 | end: '2017-04-09', 306 | }).then(data => assert.deepEqual(data, earthAssetObj)); 307 | }); 308 | }); 309 | -------------------------------------------------------------------------------- /tests/eonet.spec.js: -------------------------------------------------------------------------------- 1 | import { EONET } from 'index'; 2 | 3 | describe('EONET.events()', () => { 4 | it('returns object with array of events', () => 5 | EONET.events().then(data => { 6 | expect(data).to.be.instanceof(Object); 7 | expect(data.events).to.be.instanceof(Array); 8 | }) 9 | ); 10 | 11 | it('returns object', () => 12 | EONET.events({ eventId: 'EONET_2761' }).then(data => expect(data).to.be.instanceof(Object)) 13 | ); 14 | }); 15 | 16 | describe('EONET.categories()', () => { 17 | it('returns object with array of categories', () => 18 | EONET.categories().then(data => { 19 | expect(data).to.be.instanceof(Object); 20 | expect(data.categories).to.be.instanceof(Array); 21 | }) 22 | ); 23 | 24 | it('returns object', () => 25 | EONET.categories({ categoryId: 6 }).then(data => expect(data).to.be.instanceof(Object)) 26 | ); 27 | }); 28 | 29 | describe('EONET.sources()', () => { 30 | it('returns object with array of sources', () => 31 | EONET.sources().then(data => { 32 | expect(data).to.be.instanceof(Object); 33 | expect(data.sources).to.be.instanceof(Array); 34 | }) 35 | ); 36 | }); 37 | 38 | describe('EONET.layers()', () => { 39 | it('returns object with array of layers', () => 40 | EONET.layers().then(data => { 41 | expect(data).to.be.instanceof(Object); 42 | expect(data.categories[0].layers).to.be.instanceof(Array); 43 | }) 44 | ); 45 | 46 | it('returns object', () => 47 | EONET.layers({ categoryId: 8 }).then(data => expect(data).to.be.instanceof(Object)) 48 | ); 49 | }); 50 | -------------------------------------------------------------------------------- /tests/epic.spec.js: -------------------------------------------------------------------------------- 1 | import { EPIC } from 'index'; 2 | 3 | describe('EPIC.fetch()', () => { 4 | it('returns object', () => 5 | EPIC.fetch('natural').then(data => expect(data).to.be.instanceof(Object)) 6 | ); 7 | 8 | it('returns object', () => 9 | EPIC.fetch('enhanced').then(data => expect(data).to.be.instanceof(Object)) 10 | ); 11 | 12 | it('returns error message', () => 13 | EPIC.fetch().catch(err => expect(err).to.be.an('error')) 14 | ); 15 | 16 | it('returns error message', () => 17 | EPIC.fetch('naturale').catch(err => expect(err).to.be.an('error')) 18 | ); 19 | }); 20 | 21 | describe('EPIC.date()', () => { 22 | it('returns object', () => 23 | EPIC.date('natural', '2017-04-10').then(data => expect(data).to.be.instanceof(Object)) 24 | ); 25 | 26 | it('returns object', () => 27 | EPIC.date('enhanced', '2017-04-10').then(data => expect(data).to.be.instanceof(Object)) 28 | ); 29 | 30 | it('returns error message', () => 31 | EPIC.date().catch(err => expect(err).to.be.an('error')) 32 | ); 33 | 34 | it('returns error message', () => 35 | EPIC.date('natural').catch(err => expect(err).to.be.an('error')) 36 | ); 37 | 38 | it('returns error message', () => 39 | EPIC.date('enahnced', '2017-04-10').catch(err => expect(err).to.be.an('error')) 40 | ); 41 | 42 | it('returns error message', () => 43 | EPIC.date('enhanced', '04-10-2017').catch(err => expect(err).to.be.an('error')) 44 | ); 45 | }); 46 | 47 | describe('EPIC.all()', () => { 48 | it('returns object', () => 49 | EPIC.all('natural').then(data => expect(data).to.be.instanceof(Object)) 50 | ); 51 | 52 | it('returns object', () => 53 | EPIC.all('enhanced').then(data => expect(data).to.be.instanceof(Object)) 54 | ); 55 | 56 | it('returns error message', () => 57 | EPIC.all().catch(err => expect(err).to.be.an('error')) 58 | ); 59 | 60 | it('returns error message', () => 61 | EPIC.all('naturale').catch(err => expect(err).to.be.an('error')) 62 | ); 63 | }); 64 | 65 | describe('EPIC.available()', () => { 66 | it('returns object', () => 67 | EPIC.available('natural').then(data => expect(data).to.be.instanceof(Object)) 68 | ); 69 | 70 | it('returns object', () => 71 | EPIC.available('enhanced').then(data => expect(data).to.be.instanceof(Object)) 72 | ); 73 | 74 | it('returns error message', () => 75 | EPIC.available().catch(err => expect(err).to.be.an('error')) 76 | ); 77 | 78 | it('returns error message', () => 79 | EPIC.available('naturale').catch(err => expect(err).to.be.an('error')) 80 | ); 81 | }); 82 | -------------------------------------------------------------------------------- /tests/fireballs.spec.js: -------------------------------------------------------------------------------- 1 | import { Fireballs } from 'index'; 2 | 3 | describe('Fireballs.fetch()', () => { 4 | it('returns object', () => 5 | Fireballs.fetch().then(data => expect(data).to.be.instanceof(Object)) 6 | ); 7 | 8 | it('returns object', () => 9 | Fireballs.fetch({ 10 | 'date-min': '2015-01-05', 11 | 'date-max': '2015-01-05T05:30:20', 12 | 'energy-min': 0.3, 13 | }).then(data => expect(data).to.be.instanceof(Object)) 14 | ); 15 | 16 | it('returns object', () => 17 | Fireballs.fetch({ 18 | 'date-min': 'now', 19 | 'date-max': '+20', 20 | }).catch(err => expect(err).to.be.an('error')) 21 | ); 22 | 23 | it('returns error message', () => 24 | Fireballs.fetch({ 'date-min': '1234' }).catch(err => expect(err).to.be.an('error')) 25 | ); 26 | 27 | it('returns error message', () => 28 | Fireballs.fetch({ 29 | 'date-min': '2015-01-05', 30 | 'date-max': '2015-01-08T12', 31 | }).catch(err => expect(err).to.be.an('error')) 32 | ); 33 | }); 34 | -------------------------------------------------------------------------------- /tests/helper.js: -------------------------------------------------------------------------------- 1 | import { 2 | expect, 3 | assert, 4 | } from 'chai'; 5 | import { addPath } from 'app-module-path'; 6 | import path from 'path'; 7 | 8 | global.expect = expect; 9 | global.assert = assert; 10 | 11 | addPath(path.resolve(__dirname, `../${process.env.TEST_PATH}`)); 12 | -------------------------------------------------------------------------------- /tests/images.spec.js: -------------------------------------------------------------------------------- 1 | import { Images } from 'index'; 2 | 3 | describe('Images.search()', () => { 4 | it('returns object and collection items array', () => 5 | Images.search({ q: 'Apollo 11' }).then(data => { 6 | expect(data).to.be.instanceof(Object); 7 | expect(data.collection.items).to.be.instanceof(Array); 8 | }) 9 | ); 10 | 11 | it('returns object and collection items array', () => 12 | Images.search({ 13 | q: 'Apollo 11', 14 | description: 'moon landing', 15 | media_type: 'image', 16 | }).then(data => { 17 | expect(data).to.be.instanceof(Object); 18 | expect(data.collection.items).to.be.instanceof(Array); 19 | }) 20 | ); 21 | 22 | it('returns error message', () => 23 | Images.search().catch(err => expect(err).to.be.an('error')) 24 | ); 25 | 26 | it('returns error message', () => 27 | Images.search({ media_type: 'img,audio' }).catch(err => expect(err).to.be.an('error')) 28 | ); 29 | 30 | it('returns error message', () => 31 | Images.search({ year_start: '123-456-789' }).catch(err => expect(err).to.be.an('error')) 32 | ); 33 | }); 34 | 35 | describe('Images.asset()', () => { 36 | it('returns object and collection items array', () => 37 | Images.asset('as11-40-5874').then(data => { 38 | expect(data).to.be.instanceof(Object); 39 | expect(data.collection.items).to.be.instanceof(Array); 40 | }) 41 | ); 42 | 43 | it('returns error message', () => 44 | Images.asset().catch(err => expect(err).to.be.an('error')) 45 | ); 46 | }); 47 | 48 | describe('Images.metadata()', () => { 49 | it('returns object and specific metadata object', () => { 50 | const metadataObj = { location: 'https://images-assets.nasa.gov/image/as11-40-5874/metadata.json' }; 51 | Images.metadata('as11-40-5874').then(data => assert.deepEqual(data, metadataObj)); 52 | }); 53 | 54 | it('returns error message', () => 55 | Images.metadata().catch(err => expect(err).to.be.an('error')) 56 | ); 57 | }); 58 | 59 | describe('Images.captions()', () => { 60 | it('returns object and specific captions object', () => { 61 | const captionsObj = { location: 'https://images-assets.nasa.gov/video/172_ISS-Slosh/172_ISS-Slosh.srt' }; 62 | Images.captions('172_ISS-Slosh').then(data => assert.deepEqual(data, captionsObj)); 63 | }); 64 | 65 | it('returns error message', () => 66 | Images.captions().catch(err => expect(err).to.be.an('error')) 67 | ); 68 | }); 69 | -------------------------------------------------------------------------------- /tests/mars-photos.spec.js: -------------------------------------------------------------------------------- 1 | import { MarsPhotos } from 'index'; 2 | 3 | describe('MarsPhotos.fetch()', () => { 4 | it('returns object', () => 5 | MarsPhotos.fetch('curiosity', { sol: 5 }).then(data => 6 | expect(data).to.be.instanceof(Object)) 7 | ); 8 | 9 | it('returns object', () => 10 | MarsPhotos.fetch('perseverance', { sol: 2 }).then(data => 11 | expect(data).to.be.instanceof(Object)) 12 | ); 13 | 14 | it('returns object', () => 15 | MarsPhotos.fetch('curiosity', { 16 | camera: 'fhaz', 17 | earth_date: '2016-03-12', 18 | }).then(data => expect(data).to.be.instanceof(Object)) 19 | ); 20 | 21 | it('returns object', () => 22 | MarsPhotos.fetch('spirit', { 23 | camera: 'navcam', 24 | earth_date: '2016-03-12', 25 | page: 2, 26 | }).then(data => expect(data).to.be.instanceof(Object)) 27 | ); 28 | 29 | it('returns error message', () => 30 | MarsPhotos.fetch().catch(err => expect(err).to.be.an('error')) 31 | ); 32 | 33 | it('returns error message', () => 34 | MarsPhotos.fetch('curiosity').catch(err => expect(err).to.be.an('error')) 35 | ); 36 | 37 | it('returns error message', () => 38 | MarsPhotos.fetch('badrover').catch(err => expect(err).to.be.an('error')) 39 | ); 40 | 41 | it('returns error message', () => 42 | MarsPhotos.fetch('curiosity', { camera: 'pancam' }).catch(err => 43 | expect(err).to.be.an('error')) 44 | ); 45 | 46 | it('returns error message', () => 47 | MarsPhotos.fetch('curiosity', { earth_date: '1234' }).catch(err => 48 | expect(err).to.be.an('error')) 49 | ); 50 | }); 51 | -------------------------------------------------------------------------------- /tests/neo.spec.js: -------------------------------------------------------------------------------- 1 | import { NEO } from 'index'; 2 | 3 | describe('NEO.feed()', () => { 4 | it('returns object', () => 5 | NEO.feed().then(data => expect(data).to.be.instanceof(Object)) 6 | ); 7 | }); 8 | 9 | describe('NEO.feedToday()', () => { 10 | it('returns object', () => 11 | NEO.feedToday().then(data => expect(data).to.be.instanceof(Object)) 12 | ); 13 | }); 14 | 15 | describe('NEO.fetch()', () => { 16 | it('returns object', () => 17 | NEO.fetch('3729835').then(data => expect(data).to.be.instanceof(Object)) 18 | ); 19 | it('returns error message', () => 20 | NEO.fetch().catch(err => expect(err).to.be.an('error')) 21 | ); 22 | }); 23 | 24 | describe('NEO.browse()', () => { 25 | it('returns object', () => 26 | NEO.browse().then(data => expect(data).to.be.instanceof(Object)) 27 | ); 28 | it('returns object with 10 NEOs', () => 29 | NEO.browse({ page: 1, size: 10 }).then(data => 30 | assert.equal(data.near_earth_objects.length, 10)) 31 | ); 32 | }); 33 | 34 | describe('NEO.stats()', () => { 35 | it('returns object', () => 36 | NEO.stats().then(data => expect(data).to.be.instanceof(Object)) 37 | ); 38 | }); 39 | -------------------------------------------------------------------------------- /tests/nhats.spec.js: -------------------------------------------------------------------------------- 1 | import { NHATS } from 'index'; 2 | 3 | describe('NHATS.fetch()', () => { 4 | it('returns object', () => 5 | NHATS.fetch().then(data => expect(data).to.be.instanceof(Object)) 6 | ); 7 | }); 8 | -------------------------------------------------------------------------------- /tests/patents.spec.js: -------------------------------------------------------------------------------- 1 | import { Patents } from 'index'; 2 | 3 | describe('Patents.fetch()', () => { 4 | it('returns object', () => 5 | Patents.fetch().then(data => expect(data).to.be.instanceof(Object)) 6 | ); 7 | 8 | it('returns object with concepts', () => 9 | Patents.fetch({ query: 'temperature', concept_tags: true }).then(data => 10 | expect(data.results[0].concepts).to.be.instanceof(Object)) 11 | ); 12 | 13 | it('returns object with a single patent', () => 14 | Patents.fetch({ limit: 1 }).then(data => 15 | assert.equal(data.count, data.results.length, 1)) 16 | ); 17 | }); 18 | -------------------------------------------------------------------------------- /tests/scout.spec.js: -------------------------------------------------------------------------------- 1 | import { Scout } from 'index'; 2 | 3 | describe('Scout.fetch()', () => { 4 | it('returns object', () => 5 | Scout.fetch().then(data => expect(data).to.be.instanceof(Object)) 6 | ); 7 | }); 8 | -------------------------------------------------------------------------------- /tests/sentry.spec.js: -------------------------------------------------------------------------------- 1 | import { Sentry } from 'index'; 2 | 3 | describe('Sentry.fetch()', () => { 4 | it('returns object', () => 5 | Sentry.fetch().then(data => expect(data).to.be.instanceof(Object)) 6 | ); 7 | }); 8 | -------------------------------------------------------------------------------- /tests/sounds.spec.js: -------------------------------------------------------------------------------- 1 | import { Sounds } from 'index'; 2 | 3 | describe('Sounds.fetch()', () => { 4 | it('returns object', () => 5 | Sounds.fetch().then(data => expect(data).to.be.instanceof(Object)) 6 | ); 7 | 8 | it('returns object with a single sound object', () => 9 | Sounds.fetch({ limit: 1 }).then(data => 10 | assert.equal(data.count, data.results.length, 1)) 11 | ); 12 | }); 13 | --------------------------------------------------------------------------------