├── .gitignore ├── .lvimrc ├── .editorconfig ├── package.json ├── LICENSE ├── README.md ├── index.js └── cli.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.lvimrc: -------------------------------------------------------------------------------- 1 | let g:ale_fixers = { 2 | \ 'javascript': ['prettier_standard'], 3 | \} 4 | 5 | let g:ale_linters = {'javascript': ['']} 6 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 2 7 | indent_style = space 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@rafaelrinaldi/whereami", 3 | "version": "2.2.1", 4 | "description": "Get your geolocation information using freegeoip.app", 5 | "license": "MIT", 6 | "repository": "rafaelrinaldi/whereami", 7 | "main": "index.js", 8 | "bin": "cli.js", 9 | "engines": { 10 | "node": ">=8.6" 11 | }, 12 | "scripts": { 13 | "test": "prettier-standard *.js" 14 | }, 15 | "keywords": [ 16 | "geolocation", 17 | "location", 18 | "ip", 19 | "map", 20 | "cli" 21 | ], 22 | "dependencies": { 23 | "@mapbox/sexagesimal": "^1.2.0", 24 | "got": "^9.6.0", 25 | "loading-indicator": "^2.0.0", 26 | "minimist": "^1.2.0" 27 | }, 28 | "devDependencies": { 29 | "prettier-standard": "^8.0.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Rafael Rinaldi (rinaldi.io) 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # whereami [![Build Status](https://semaphoreci.com/api/v1/projects/a5332a07-61aa-49f9-90e6-49844c5e2231/665179/badge.svg)](https://semaphoreci.com/rafaelrinaldi/whereami) 2 | 3 | > Get your geolocation information using [freegeoip.app](http://freegeoip.app) 4 | 5 | ## Install 6 | 7 | ```sh 8 | $ npm install -g @rafaelrinaldi/whereami 9 | ``` 10 | 11 | ## Usage 12 | 13 | ```sh 14 | Usage: whereami [OPTIONS] 15 | 16 | Get your geolocation information using freegeoip.app 17 | 18 | Example: 19 | $ whereami 20 | -23.4733,-46.6658 21 | 22 | $ whereami -f human 23 | San Francisco, CA, United States 24 | 25 | $ whereami 2.151.255.255 -f human 26 | Stabekk, Akershus, Norway 27 | 28 | Options: 29 | -v --version Display current software version 30 | -h --help Display help and usage details 31 | -f --format Output format (either human, json or sexagesimal) 32 | -r --raw Output raw data from freegeoip.app 33 | ``` 34 | 35 | ## License 36 | 37 | MIT © [Rafael Rinaldi](rinaldi.io) 38 | 39 | --- 40 | 41 |

42 | Buy me a ☕ 43 |

44 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const got = require('got') 2 | const sexagesimal = require('@mapbox/sexagesimal') 3 | const headers = { 4 | 'user-agent': 'https://github.com/rafaelrinaldi/whereami' 5 | } 6 | 7 | const formatToJson = ({ latitude, longitude }) => 8 | JSON.stringify({ 9 | latitude, 10 | longitude 11 | }) 12 | 13 | const formatToSexagesimal = data => { 14 | const latitude = sexagesimal.format(data.latitude, 'lat') 15 | const longitude = sexagesimal.format(data.longitude, 'lon') 16 | 17 | return `${latitude},${longitude}` 18 | } 19 | 20 | const formatToHuman = data => { 21 | if (!data.country_name && !data.region_name && !data.city) { throw new Error('Unable to retrieve region') } 22 | 23 | return [data.city, data.region_name, data.country_name] 24 | .filter(Boolean) 25 | .join(', ') 26 | } 27 | 28 | const formatOutput = (data, options) => { 29 | if (options.raw) return JSON.stringify(data, null, 2) 30 | 31 | const mapFormatToFormatter = { 32 | sexagesimal: formatToSexagesimal, 33 | json: formatToJson, 34 | human: formatToHuman 35 | } 36 | 37 | return mapFormatToFormatter[options.format](data) 38 | } 39 | 40 | const whereami = ({ ipOrHostname = '', ...options }) => 41 | got(`freegeoip.app/json/${ipOrHostname}`, { headers }).then(({ body }) => 42 | formatOutput(JSON.parse(body), options) 43 | ) 44 | 45 | module.exports = whereami 46 | -------------------------------------------------------------------------------- /cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const whereami = require('./') 4 | const minimist = require('minimist') 5 | const Loading = require('loading-indicator') 6 | const options = { 7 | boolean: ['help', 'version', 'raw'], 8 | alias: { 9 | h: 'help', 10 | v: 'version', 11 | f: 'format', 12 | r: 'raw' 13 | }, 14 | default: { 15 | raw: false, 16 | format: 'sexagesimal' 17 | } 18 | } 19 | 20 | const argv = minimist(process.argv.slice(2), options) 21 | const [ipOrHostname] = argv._ 22 | 23 | const help = ` 24 | Usage: whereami [OPTIONS] 25 | 26 | Get your geolocation information using freegeoip.net from the CLI 27 | 28 | Example: 29 | $ whereami 30 | -23.4733,-46.6658 31 | 32 | $ whereami -f human 33 | San Francisco, CA, United States 34 | 35 | $ whereami 2.151.255.255 -f human 36 | Stabekk, Akershus, Norway 37 | 38 | Options: 39 | -v --version Display current software version 40 | -h --help Display help and usage details 41 | -f --format Output format (either human, json or sexagesimal) 42 | -r --raw Output raw data from freegeoip.net 43 | ` 44 | 45 | function exitWithSuccess (message) { 46 | process.stdout.write(`${message}\n`) 47 | process.exit(0) 48 | } 49 | 50 | function exitWithError (message, code = 1) { 51 | process.stderr.write(`${message}\n`) 52 | process.exit(code) 53 | } 54 | 55 | if (argv.help) exitWithSuccess(help) 56 | if (argv.version) exitWithSuccess(require('./package.json').version) 57 | 58 | const isValidFormat = ['human', 'json', 'sexagesimal'].includes(argv.format) 59 | 60 | if (!isValidFormat) exitWithError(`Format "${argv.format}" is not supported`) 61 | 62 | async function run () { 63 | const loading = Loading.start() 64 | 65 | try { 66 | const output = await whereami({ ...argv, ipOrHostname }) 67 | Loading.stop(loading) 68 | exitWithSuccess(output) 69 | } catch (error) { 70 | Loading.stop(loading) 71 | exitWithError(error.message) 72 | } 73 | } 74 | 75 | run() 76 | --------------------------------------------------------------------------------