dark-sky-api
Advanced tools
Comparing version 0.0.32 to 0.1.0
@@ -0,0 +0,0 @@ 'use strict'; |
{ | ||
"name": "dark-sky-api", | ||
"version": "0.0.32", | ||
"description": "A simple dark sky api wrapper for client side js supporting use of proxy and using method chaining and promises", | ||
"version": "0.1.0", | ||
"description": "a simple and robust dark sky api service for client-side js", | ||
"main": "index.js", | ||
@@ -36,7 +36,5 @@ "scripts": { | ||
"dependencies": { | ||
"fetch-jsonp": "^1.0.6", | ||
"moment": "^2.18.1", | ||
"query-string": "^4.3.2", | ||
"whatwg-fetch": "^2.0.3" | ||
"dark-sky-skeleton": "^0.1.1", | ||
"moment": "^2.18.1" | ||
} | ||
} |
# dark-sky-api | ||
*Based on Elias Hussary's [dark-sky](https://github.com/eliash91/dark-sky).* | ||
A simple and robust wrapper library for Dark Sky API (previously known as Forecast.io). | ||
A wrapper library for Dark Sky API (previously known as Forecast.io). See Dark Sky developer docs: [https://darksky.net/dev/docs](https://darksky.net/dev/docs). | ||
Features: | ||
* Simple to use. | ||
* Promise based (es6-promises). | ||
* Versatile - use it statically or instantiate it. | ||
* Dates returned as [moments](https://momentjs.com/). | ||
* Excludes are used automatically to reduce latency and save cache space ([see 'Request Parameters'](https://darksky.net/dev/docs/forecast)). | ||
See Dark Sky developer docs: [https://darksky.net/dev/docs](https://darksky.net/dev/docs). | ||
Need something even smaller? Dark sky api uses [dark-sky-skeleton](https://github.com/deanbot/dark-sky-skeleton). | ||
### Install it | ||
@@ -15,14 +25,19 @@ | ||
```javascript | ||
import darkSkyApi from 'dark-sky-api'; | ||
import DarkSkyApi from 'dark-sky-api'; | ||
``` | ||
### Initialize it | ||
### Configure it statically (suggested) | ||
While dark-sky-api allows embedding api keys through use of jsonp on the backend using a proxy to make the api call is highly suggested as this hides the API key from client side requests [[ref](https://darksky.net/dev/docs/faq#cross-origin)]. | ||
Configuring dark-sky-api with an api key is supported but each request will expose said api key (for anyone to capture). | ||
* proxy url is optional | ||
* pass an empty string or false for api key if using proxy url | ||
For this reason Dark Sky strongly suggests hiding your API key through use of a proxy [[ref](https://darksky.net/dev/docs/faq#cross-origin)]. | ||
```javascript | ||
const darkSky = new darkSkyApi('your-dark-sky-api-key', '//base-url-to-proxy/service'); | ||
// one of the two is required | ||
DarkSkyApi.apiKey = 'your-dark-sky-api-key'; | ||
DarkSkyApi.proxyUrl = '//base-url-to-proxy/service'; | ||
// optional configuration | ||
DarkSkyApi.units = 'si'; // default 'us' | ||
DarkSKyApi.language = 'de'; // default 'en' | ||
``` | ||
@@ -32,31 +47,43 @@ | ||
Today's weather: | ||
```javascript | ||
darkSky.latitude(lat) | ||
.longitude(long) | ||
.get(); | ||
.then(data => console.log(data)); | ||
DarkSkyApi.getCurrent() | ||
.then(result => console.log(result)); | ||
``` | ||
Feel free to omit setting of latitude and longitude for subsequent calls i.e.: | ||
Forecasted week of weather: | ||
```javascript | ||
const darkSky = new darkSkyApi('your-dark-sky-api-key'); | ||
darkSky.latitude(lat) | ||
.longitude(long); | ||
DarkSkyApi.getForecast() | ||
.then(result => console.log(result)); | ||
``` | ||
darkSky.get(); | ||
### What about geo location? | ||
By default dark-sky-api will use [Geolocation.getCurrentPosition](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/getCurrentPosition) to grab the current browser location automatically. | ||
To manually set geolocation position pass along a position object: | ||
```javascript | ||
const position = { | ||
latitude: 43.075284, | ||
longitude: -89.384318 | ||
}; | ||
DarkSkyApi.getCurrent(position) | ||
.then(result => console.log(result)); | ||
``` | ||
### Make use of excludes | ||
### Response units | ||
"Exclude some number of data blocks from the API response. This is useful for reducing latency and saving cache space ([see 'Request Parameters'](https://darksky.net/dev/docs/forecast))." | ||
To get the units used in dark sky api responses per configured unit type (default is 'us') use GetResponseUnits after configuration. | ||
```javascript | ||
const excludes = ['alerts', 'currently', 'daily', 'flags', 'hourly', 'minutely'], | ||
exludesBlock = excludes.filter(val => val != 'currently').join(',') | ||
darkSky.latitude(lat) | ||
.longitude(long) | ||
.exclude(excludesBlock) | ||
.get() | ||
.then(data => console.log(data)); | ||
const units = DarkSkyApi.getResponseUnits(); | ||
``` | ||
#### To Do | ||
* show examples of instantiation | ||
* show example of using results with units | ||
* add hourly and minutely api methods | ||
* add flags and alerts apit methods |
@@ -0,91 +1,320 @@ | ||
import darkSkySkeleton from 'dark-sky-skeleton'; | ||
import moment from 'moment'; | ||
import queryString from 'query-string'; | ||
import fetchJsonp from 'fetch-jsonp'; | ||
import fetch from 'whatwg-fetch'; | ||
import { getNavigatorCoords, degreeToCardinal } from 'geo-loc-utils'; | ||
const config = { | ||
storageKeyCurrent: 'weather-data-current', | ||
storageKeyForecast: 'weather-data-forecast', | ||
errorMessage: { | ||
noApiKeyOrProxyUrl: 'No Dark Sky api key set and no proxy url set' | ||
}, | ||
warningMessage: { | ||
cantGuessUnits: 'Can\'t guess units. Defaulting to Imperial', | ||
invalidUnit: 'not an accepted API unit.', | ||
invalidLanguage: 'not an accepted API lanugage.' | ||
}, | ||
excludes: ['alerts', 'currently', 'daily', 'flags', 'hourly', 'minutely'], | ||
acceptedUnits: ['auto', 'ca', 'uk2', 'us', 'si'], | ||
acceptedLanguage: [ | ||
'ar', 'az', 'be', 'bs', 'cs', 'de', 'el', 'en', 'es', 'fr', 'hr', 'hu', 'id', 'it', 'is', 'kw', 'nb', 'nl', 'pl', 'pt', 'ru', 'sk', 'sr', 'sv', 'tet', 'tr', 'uk', 'x-pig-latin', 'zh', 'zh-tw' | ||
] | ||
}; | ||
class DarkSkyApi { | ||
constructor(apiKey, proxyUrl) { | ||
this.proxyUrl = proxyUrl || ''; | ||
this.apiKey = apiKey || ''; | ||
this._longitude = null; | ||
this._latitude = null; | ||
this._time = null; | ||
this.query = {}; | ||
} | ||
// darkSkyApi; instance of dark sky skeleton | ||
// initialized; weather the instance of dark sky api has lat and long set | ||
// _units; | ||
// _language; | ||
longitude(long) { | ||
!long ? null : this._longitude = long; | ||
return this; | ||
/** | ||
* @param {string} apiKey - dark sky api key - consider using a proxy | ||
* @param {string} proxyUrl - make request behind proxy to hide api key | ||
*/ | ||
constructor(apiKey, proxyUrl, units, language) { | ||
this.darkSkyApi = new darkSkySkeleton(apiKey, proxyUrl); | ||
this._units = units || 'us'; | ||
this._language = language || 'en'; | ||
} | ||
latitude(lat) { | ||
!lat ? null : this._latitude = lat; | ||
/** | ||
* Initialze dark sky api with position data - Chainable | ||
* @param {object} position - containing geo latitude and longitude | ||
* @see WeatherApi.getNavigatorCoords | ||
*/ | ||
initialize = (position) => { | ||
this.setPosition(position); | ||
this.initialized = true; | ||
return this; | ||
} | ||
time(time) { | ||
!time ? null : this._time = moment(time).format('YYYY-MM-DDTHH:mm:ss'); | ||
/** | ||
* Set dark sky api position data - Chainable | ||
* @param {object} position - containing geo latitude and longitude | ||
*/ | ||
setPosition = ({ latitude, longitude }) => { | ||
this.darkSkyApi | ||
.latitude(latitude) | ||
.longitude(longitude); | ||
return this; | ||
} | ||
units(unit) { | ||
!unit ? null : this.query.units = unit; | ||
/** | ||
* Set unit type for response formatting - Chainable | ||
* @param {String} value - unit token | ||
*/ | ||
units(value) { | ||
if (config.acceptedUnits.indexOf(value) === -1) { | ||
console.warn(`${value} ${config.warningMessage.invalidUnit}`); // eslint-disable-line no-console | ||
} else { | ||
!value ? null : this._units = value; | ||
} | ||
return this; | ||
} | ||
language(lang) { | ||
!lang ? null : this.query.lang = lang; | ||
/** | ||
* Set language for response summaries | ||
* @param {String} value - language token | ||
*/ | ||
language(value) { | ||
if (config.acceptedLanguage.indexOf(value) === -1) { | ||
console.warn(`${value} ${config.warningMessage.invalidLanguage}`); // eslint-disable-line no-console | ||
} else { | ||
!value ? null : this._language = value; | ||
} | ||
return this; | ||
} | ||
exclude(blocks) { | ||
!blocks ? null : this.query.exclude = blocks; | ||
return this; | ||
/** | ||
* Get forecasted week of weather | ||
*/ | ||
loadCurrent() { | ||
if (!this.initialized) { | ||
return this.loadPositionAsync() | ||
.then(position => this.initialize(position).loadCurrent()); | ||
} | ||
return this.darkSkyApi | ||
.units(this._units) | ||
.language(this._language) | ||
.exclude(config.excludes.filter(val => val != 'currently').join(',')) | ||
.get() | ||
.then(({ currently }) => { | ||
currently.windDirection = degreeToCardinal(currently.windBearing); | ||
if (currently.nearestStormBearing) { | ||
currently.nearestStormDirection = degreeToCardinal(currently.nearestStormBearing); | ||
} | ||
return currently; | ||
}); | ||
} | ||
extendHourly(param) { | ||
!param ? null : this.query.extend = 'hourly'; | ||
return this; | ||
/** | ||
* Get forecasted week of weather | ||
*/ | ||
loadForecast() { | ||
if (!this.initialized) { | ||
return this.loadPositionAsync() | ||
.then(position => this.initialize(position).loadCurrent()); | ||
} | ||
return this.darkSkyApi | ||
.units(this._units) | ||
.language(this._language) | ||
.exclude(config.excludes.filter(val => val != 'daily').join(',')) | ||
.get() | ||
.then(data => { | ||
console.log(data); // eslint-disable-line no-console | ||
}); | ||
} | ||
generateReqUrl() { | ||
const baseUrl = this.proxyUrl ? this.proxyUrl : `https://api.darksky.net/forecast/${this.apiKey}`; | ||
this.url = `${baseUrl}/${this._latitude},${this._longitude}`; | ||
this._time | ||
? this.url += `,${this._time}` | ||
: this.url; | ||
!this.isEmpty(this.query) | ||
? this.url += `?${queryString.stringify(this.query)}` | ||
: this.url; | ||
/** | ||
* Get units object showing units returned based on configured units | ||
* @returns {object} units | ||
*/ | ||
getResponseUnits() { | ||
let unitsObject, unitsId; | ||
if (this._units === 'auto') { | ||
console.warn(config.warningMessage.cantGuessUnits); // eslint-disable-line no-console | ||
unitsId = 'us'; | ||
} else { | ||
unitsId = this._units; | ||
} | ||
// get units object by id | ||
switch (unitsId) { | ||
case 'us': | ||
unitsObject = WeatherApi.getUsUnits(); | ||
break; | ||
case 'ca': | ||
unitsObject = WeatherApi.getCaUnits(); | ||
break; | ||
case 'uk2': | ||
unitsObject = WeatherApi.getUk2Units(); | ||
break; | ||
case 'si': | ||
unitsObject = WeatherApi.getSiUnits(); | ||
break; | ||
} | ||
return unitsObject; | ||
} | ||
get() { | ||
if (!this._latitude || !this._longitude) { | ||
return new Promise((resolve, reject) => { | ||
reject("Request not sent. ERROR: Longitute or Latitude is missing."); | ||
}); | ||
/** | ||
* Get browser navigator coords - Promise | ||
*/ | ||
loadPositionAsync = WeatherApi.loadPositionAsync; | ||
static _api; | ||
// allow config and deferring of initialization | ||
static apiKey; | ||
static proxyUrl; | ||
static units; | ||
static language; | ||
/** | ||
* Get browser navigator coords - Promise | ||
*/ | ||
static loadPositionAsync = () => getNavigatorCoords(); | ||
/** | ||
* Initialize a static instance of weather api with dark sky api key | ||
* @param {string} apiKey | ||
* @param {string} proxyUrl | ||
*/ | ||
static initialize(apiKey, proxyUrl, units, language) { | ||
if (this._api) { | ||
return; | ||
} | ||
this.generateReqUrl(); | ||
const query = this.proxyUrl ? fetch(this.url) : fetchJsonp(this.url); | ||
if (!this.apiKey && !this.proxyUrl && !apiKey && !proxyUrl) { | ||
throw new Error(config.errorMessage.noApiKeyOrProxyUrl); | ||
} | ||
return query.then(function (response) { | ||
return response.json(); | ||
}).then(function (json) { | ||
return json; | ||
}).catch(function (ex) { | ||
return ex; | ||
}); | ||
const key = apiKey || this.apiKey || ''; | ||
const proxy = proxyUrl || this.proxyUrl || ''; | ||
const unit = units || this.units || ''; | ||
const lang = language || this.language || ''; | ||
this._api = new WeatherApi(key, proxy, unit, lang); | ||
} | ||
isEmpty(obj) { | ||
for (let key in obj) { | ||
if (obj.hasOwnProperty(key)) { | ||
return false; | ||
} | ||
/** | ||
* Get units object showing units returned based on configured units - initialize or configure with api key or proxy first | ||
* @returns {object} units | ||
*/ | ||
static getResponseUnits() { | ||
this.initialize(); | ||
return this._api.getResponseUnits(); | ||
} | ||
/** | ||
* Set unit type for response formatting - initialize or configure with api key or proxy first | ||
* @param {String} value - unit token | ||
*/ | ||
static setUnits(units) { | ||
this.initialize(); | ||
this._api.units(units); | ||
} | ||
/** | ||
* Set language for response summaries - initialize or configure with api key or proxy first | ||
* @param {String} value - language token | ||
*/ | ||
static setLanguage(language) { | ||
this.initialize(); | ||
this._api.language(language); | ||
} | ||
/** | ||
* Get today's weather - Promise | ||
* @param {object} [position] - if omitted will use loadPositionAsync | ||
*/ | ||
static loadCurrent(position) { | ||
this.initialize(); | ||
if (position) { | ||
return this._api | ||
.setPosition(position) | ||
.loadCurrent(); | ||
} else { | ||
return this._api.loadCurrent(); | ||
} | ||
return true; | ||
} | ||
/** | ||
* Get forecasted week of weather - Promise | ||
* @param {object} [position] - if omitted api will use loadPositionAsync | ||
*/ | ||
static loadForecast(position) { | ||
this.initialize(); | ||
if (position) { | ||
return this._api | ||
.setPosition(position) | ||
.loadForecast(); | ||
} else { | ||
return this._api.loadForecast(); | ||
} | ||
} | ||
/** | ||
* Return the us response units | ||
* @return {object} units | ||
*/ | ||
static getUsUnits() { | ||
return { | ||
nearestStormDistance: 'mi', | ||
precipIntensity: 'in/h', | ||
precipIntensityMax: 'in/h', | ||
precipAccumulation: 'in', | ||
temperature: 'f', | ||
temperatureMin: 'f', | ||
temperatureMax: 'f', | ||
apparentTemperature: 'f', | ||
dewPoint: 'f', | ||
windSpeed: 'mph', | ||
pressure: 'mbar', | ||
visibility: 'mi' | ||
}; | ||
} | ||
/** | ||
* Return the si response units | ||
* @return {object} units | ||
*/ | ||
static getSiUnits() { | ||
return { | ||
nearestStormDistance: 'km', | ||
precipIntensity: 'mm/h', | ||
precipIntensityMax: 'mm/h', | ||
precipAccumulation: 'cm', | ||
temperature: 'c', | ||
temperatureMin: 'c', | ||
temperatureMax: 'c', | ||
apparentTemperature: 'c', | ||
dewPoint: 'c', | ||
windSpeed: 'mps', | ||
pressure: 'hPa', | ||
visibility: 'km' | ||
}; | ||
} | ||
/** | ||
* Return ca response units | ||
* @return {object} units | ||
*/ | ||
static getCaUnits() { | ||
let unitsObject = this.getUsUnits(); | ||
unitsObject.windSpeed = 'km/h'; | ||
return unitsObject; | ||
} | ||
/** | ||
* Return uk2 response units | ||
* @return {object} units | ||
*/ | ||
static getUk2Units() { | ||
let unitsObject = this.getSiUnits(); | ||
unitsObject.nearestStormDistance = unitsObject.visibility = 'mi'; | ||
unitsObject.windSpeed = 'mph'; | ||
return unitsObject; | ||
} | ||
} | ||
export default DarkSkyApi; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
20904
2
9
538
87
+ Addeddark-sky-skeleton@^0.1.1
+ Addeddark-sky-skeleton@0.1.46(transitive)
+ Addedencoding@0.1.13(transitive)
+ Addediconv-lite@0.6.3(transitive)
+ Addedis-stream@1.1.0(transitive)
+ Addedisomorphic-fetch@2.2.1(transitive)
+ Addednode-fetch@1.7.3(transitive)
+ Addedsafer-buffer@2.1.2(transitive)
+ Addedwhatwg-fetch@3.6.20(transitive)
- Removedfetch-jsonp@^1.0.6
- Removedquery-string@^4.3.2
- Removedwhatwg-fetch@^2.0.3
- Removedwhatwg-fetch@2.0.4(transitive)