@adamlui/geolocate 2.0.15 โ 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -10
- package/dist/cli/index.min.js +5 -14
- package/dist/cli/lib/data.min.js +4 -4
- package/dist/cli/lib/language.min.js +6 -4
- package/dist/cli/lib/log.min.js +23 -0
- package/dist/cli/lib/settings.min.js +8 -0
- package/dist/data/app.json +2 -1
- package/dist/data/geolocate.config.mjs +13 -0
- package/dist/data/messages.json +24 -4
- package/dist/geolocate.min.js +4 -4
- package/docs/README.md +30 -10
- package/package.json +9 -4
package/README.md
CHANGED
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
<img height=31 src="https://img.shields.io/npm/dm/@adamlui/geolocate?logo=npm&color=af68ff&logoColor=white&labelColor=464646&style=for-the-badge"></a>
|
|
9
9
|
<a href="#%EF%B8%8F-mit-license">
|
|
10
10
|
<img height=31 src="https://img.shields.io/badge/License-MIT-orange.svg?logo=internetarchive&logoColor=white&labelColor=464646&style=for-the-badge"></a>
|
|
11
|
-
<a href="https://github.com/adamlui/js-utils/releases/tag/geolocate-2.0
|
|
12
|
-
<img height=31 src="https://img.shields.io/badge/Latest_Build-2.0
|
|
11
|
+
<a href="https://github.com/adamlui/js-utils/releases/tag/geolocate-2.1.0">
|
|
12
|
+
<img height=31 src="https://img.shields.io/badge/Latest_Build-2.1.0-44cc11.svg?logo=icinga&logoColor=white&labelColor=464646&style=for-the-badge"></a>
|
|
13
13
|
<a href="https://www.npmjs.com/package/@adamlui/geolocate?activeTab=code">
|
|
14
14
|
<img height=31 src="https://img.shields.io/npm/unpacked-size/%40adamlui%2Fgeolocate?style=for-the-badge&logo=ebox&logoColor=white&labelColor=464646&color=blue"></a>
|
|
15
|
-
<a href="https://github.com/adamlui/js-utils/blob/geolocate-2.0
|
|
16
|
-
<img height=31 src="https://img.shields.io/github/size/adamlui/js-utils/geolocate/dist/geolocate.min.js?branch=geolocate-2.0
|
|
15
|
+
<a href="https://github.com/adamlui/js-utils/blob/geolocate-2.1.0/geolocate/dist/geolocate.min.js">
|
|
16
|
+
<img height=31 src="https://img.shields.io/github/size/adamlui/js-utils/geolocate/dist/geolocate.min.js?branch=geolocate-2.1.0&label=Minified%20Size&logo=databricks&logoColor=white&labelColor=464646&color=ff69b4&style=for-the-badge"></a>
|
|
17
17
|
<a href="https://sonarcloud.io/component_measures?metric=new_vulnerabilities&id=adamlui_js-utils:geolocate/src/geolocate.js">
|
|
18
18
|
<img height=31 src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fsonarcloud.io%2Fapi%2Fmeasures%2Fcomponent%3Fcomponent%3Dadamlui_js-utils%3Ageolocate%2Fsrc%2Fgeolocate.js%26metricKeys%3Dvulnerabilities&query=%24.component.measures.0.value&style=for-the-badge&logo=sonarcloud&logoColor=white&labelColor=464646&label=Vulnerabilities&color=gold"></a>
|
|
19
19
|
<a href="https://github.com/toolleeo/cli-apps#networking">
|
|
@@ -66,14 +66,34 @@ Sample output:
|
|
|
66
66
|
### Command line options
|
|
67
67
|
|
|
68
68
|
```
|
|
69
|
+
Parameter options:
|
|
70
|
+
--config="path/to/file" Load custom config file.
|
|
71
|
+
|
|
69
72
|
Boolean options:
|
|
70
73
|
-q, --quiet Suppress all logging except errors.
|
|
71
74
|
|
|
72
|
-
|
|
75
|
+
Commands:
|
|
76
|
+
-i, --init Create config file (in project root).
|
|
73
77
|
-h, --help Display help screen.
|
|
74
78
|
-v, --version Show version number.
|
|
75
79
|
```
|
|
76
80
|
|
|
81
|
+
#
|
|
82
|
+
|
|
83
|
+
### Configuration file
|
|
84
|
+
|
|
85
|
+
**generate-ip** can be customized using a `geolocate.config.mjs` or `geolocate.config.js` placed in your project root.
|
|
86
|
+
|
|
87
|
+
Example defaults:
|
|
88
|
+
|
|
89
|
+
```js
|
|
90
|
+
export default {
|
|
91
|
+
quietMode: false // suppress all logging except errors
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
๐ก Run `geolocate init` to generate a template `geolocate.config.mjs` in your project root.
|
|
96
|
+
|
|
77
97
|
<br>
|
|
78
98
|
|
|
79
99
|
<img height=6px width="100%" src="https://assets.js-utils.org/images/separators/aqua-gradient.png?v=0d36e26">
|
|
@@ -87,7 +107,7 @@ You can also import **geolocate** into your app to use its main API method.
|
|
|
87
107
|
#### ECMAScript*:
|
|
88
108
|
|
|
89
109
|
```js
|
|
90
|
-
import geo from '@adamlui/geolocate'
|
|
110
|
+
import geo from '@adamlui/geolocate'
|
|
91
111
|
```
|
|
92
112
|
|
|
93
113
|
#### CommonJS:
|
|
@@ -103,14 +123,14 @@ const geo = require('@adamlui/geolocate')
|
|
|
103
123
|
#### <> HTML script tag:
|
|
104
124
|
|
|
105
125
|
```html
|
|
106
|
-
<script src="https://cdn.jsdelivr.net/npm/@adamlui/geolocate@2.0
|
|
126
|
+
<script src="https://cdn.jsdelivr.net/npm/@adamlui/geolocate@2.1.0/dist/geolocate.min.js"></script>
|
|
107
127
|
```
|
|
108
128
|
|
|
109
129
|
#### ES6:
|
|
110
130
|
|
|
111
131
|
```js
|
|
112
132
|
(async () => {
|
|
113
|
-
await import('https://cdn.jsdelivr.net/npm/@adamlui/geolocate@2.0
|
|
133
|
+
await import('https://cdn.jsdelivr.net/npm/@adamlui/geolocate@2.1.0/dist/geolocate.min.js')
|
|
114
134
|
// Your code here...
|
|
115
135
|
})()
|
|
116
136
|
```
|
|
@@ -119,7 +139,7 @@ const geo = require('@adamlui/geolocate')
|
|
|
119
139
|
|
|
120
140
|
```js
|
|
121
141
|
...
|
|
122
|
-
// @require https://cdn.jsdelivr.net/npm/@adamlui/geolocate@2.0
|
|
142
|
+
// @require https://cdn.jsdelivr.net/npm/@adamlui/geolocate@2.1.0/dist/geolocate.min.js
|
|
123
143
|
// ==/UserScript==
|
|
124
144
|
|
|
125
145
|
// Your code here...
|
|
@@ -127,7 +147,7 @@ const geo = require('@adamlui/geolocate')
|
|
|
127
147
|
|
|
128
148
|
<br>
|
|
129
149
|
|
|
130
|
-
**๐ Note:** To always import the latest version (not recommended in production!) remove the `@2.0
|
|
150
|
+
**๐ Note:** To always import the latest version (not recommended in production!) remove the `@2.1.0` version tag from the jsDelivr URL: `https://cdn.jsdelivr.net/npm/@adamlui/geolocate/dist/geolocate.min.js`
|
|
131
151
|
|
|
132
152
|
<br>
|
|
133
153
|
|
package/dist/cli/index.min.js
CHANGED
|
@@ -1,17 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* ยฉ 2024โ2026 Adam Lui & contributors under the MIT license.
|
|
4
|
+
* Source: https://github.com/adamlui/js-utils/tree/main/geolocate/src
|
|
5
|
+
* Documentation: https://github.com/adamlui/js-utils/tree/main/geolocate/docs
|
|
6
6
|
*/
|
|
7
|
-
(async()=>{globalThis.env={
|
|
8
|
-
${
|
|
9
|
-
${r.by}${app.msgs.info_validArgs}.`+r.nc),m(["paramOptions","infoCmds"]),process.exit(1)))}),process.argv.some(e=>app.regex.infoCmds.help.test(e)))m();else if(process.argv.some(e=>app.regex.infoCmds.version.test(e))){n=s(`npm view ${JSON.stringify(app.name)} version`).toString().trim()||"none";let e,o=process.cwd();for(;"/"!=o;){var c=i.join(o,"package.json");if(p.existsSync(c)){c=require(c);e=(c.dependencies?.[app.name]||c.devDependencies?.[app.name])?.match(/^[~^>=]?\d+\.\d+\.\d+$/)?.[1]||"none";break}o=i.dirname(o)}console.info(`
|
|
10
|
-
${app.msgs.prefix_globalVer}: `+n),console.info(app.msgs.prefix_localVer+": "+e)}else{var g,t,l=[];for(g of process.argv.slice(2))g.startsWith("-")||(t=g.replace(/[[\]]/g,""),l.push(t));a=await o.locate(l,{verbose:!app.config.quietMode});a||process.exit(1),app.config.quietMode||1!=a.length||(console.info(`
|
|
11
|
-
IP: `+r.bw+a[0].ip+r.nc),console.info(`${app.msgs.geoLabel_country}: ${r.bw}${a[0].country}${r.nc}}`),console.info(`${app.msgs.geoLabel_region}: ${r.bw}${a[0].regionName}${r.nc}}`),console.info(`${app.msgs.geoLabel_city}: ${r.bw}${a[0].city}${r.nc}}`),console.info(`${app.msgs.geoLabel_zip}: ${r.bw}${a[0].zip}${r.nc}}`),console.info(`${app.msgs.geoLabel_lat}: ${r.bw}${a[0].lat}${r.nc}}`),console.info(`${app.msgs.geoLabel_lon}: ${r.bw}${a[0].lon}${r.nc}}`),console.info(app.msgs.geoLabel_timeZone+": "+r.bw+a[0].timezone.replace(/_/g," ").replace(/\//g," / ")+r.nc),console.info(`ISP: ${r.bw}${a[0].isp}${r.nc}}`)),s=`
|
|
12
|
-
${app.msgs.info_copying}...`,app.config.quietMode||console.info(s),e.writeSync(JSON.stringify(a,void 0,2))}function m(e=["header","usage","configOptions","infoCmds"]){app.prefix=`[106m[30m ${app.name.replace(/^@[^/]+\//,"")} ${r.nc} `;let o={header:[`
|
|
13
|
-
โ ${app.prefix}${app.msgs.appCopyright||`ยฉ ${app.copyrightYear} ${app.author} under the ${app.license} license`}.`,""+app.prefix+app.msgs.prefix_source+": "+app.urls.src],usage:[`
|
|
14
|
-
${r.bw}o ${app.msgs.helpSection_usage}:`+r.nc,` ${r.bw}ยป `+r.bg+app.cmdFormat+r.nc],configOptions:[`
|
|
15
|
-
${r.bw}o ${app.msgs.helpSection_configOptions}:`+r.nc,` -q, --quiet ${app.msgs.optionDesc_quiet}.`],infoCmds:[`
|
|
16
|
-
${r.bw}o ${app.msgs.helpSection_infoCmds}:`+r.nc," -h, --help "+app.msgs.optionDesc_help,` -v, --version ${app.msgs.optionDesc_version}.`]};e.forEach(i=>o[i]?.forEach(o=>{{var a=/header|usage/.test(i)?1:29;let s=process.stdout.columns||80,p=[],e=o.match(/\S+|\s+/g),n="";e.forEach(e=>{var o=s-(p.length?a:0);n.length+"| ".length+e.length>o&&(p.push(p.length?n.trimStart():n),n=""),n+=e}),p.push(p.length?n.trimStart():n),p.forEach((e,o)=>console.info("| "+(0==o?e:" ".repeat(a)+e)))}})),console.info(`
|
|
17
|
-
${app.msgs.info_moreHelp}, ${app.msgs.info_visit}: `+r.bw+app.urls.docs+r.nc)}})();
|
|
7
|
+
(async()=>{var e,i=process.argv.slice(2),o=(globalThis.env={debugMode:i.some(e=>/^--?debug(?:-?mode)?$/.test(e)),devMode:/[\\/]src(?:[\\/]|$)/i.test(__dirname)},require("node-clipboardy")),s=require(`../geolocate${env.devMode?"":".min"}.js`),{generateRandomLang:n,getMsgs:r,getSysLang:t}=require(`./lib/language${env.devMode?"":".min"}.js`),a=require(`./lib/log${env.devMode?"":".min"}.js`),g=require(`./lib/settings${env.devMode?"":".min"}.js`),d=(Object.assign(globalThis.app??={},require(`../${env.devMode?"../":"./data/"}app.json`)),app.msgs=await r(env.debugMode?n({excludes:["en"]}):t()),app.urls.docs+="/#-command-line-usage",[]);for(e of i){var l=g.controls.init.regex.test(e);if(l)return g.initConfigFile();if(g.controls.help.regex.test(e))return a.help();if(g.controls.version.regex.test(e))return a.version();e.startsWith("-")||l||d.push(e.replace(/[[\]]/g,""))}g.load();r=await s.locate(d,{verbose:!app.config.quietMode});r||process.exit(1),app.config.quietMode||1!=r.length||a.geoData(r[0]),a.ifNotQuiet(`
|
|
8
|
+
${app.msgs.info_copyingToClip}...`),o.writeSync(JSON.stringify(r,void 0,2))})();
|
package/dist/cli/lib/data.min.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* ยฉ 2024โ2026 Adam Lui & contributors under the MIT license.
|
|
3
|
+
* Source: https://github.com/adamlui/js-utils/tree/main/geolocate/src
|
|
4
|
+
* Documentation: https://github.com/adamlui/js-utils/tree/main/geolocate/docs
|
|
5
5
|
*/
|
|
6
|
-
module.exports={fetch(n){return new Promise((t,e)=>{var r=n.match(/^([^:]+):\/\//)[1];/^https?$/.test(r)||e(new Error(app.msgs.error_invalidURL+".")),require(r).get(n,e=>{let r="";e.on("data",e=>r+=e),e.on("end",()=>t({json:()=>JSON.parse(r)}))}).on("error",e)})},flatten(e,{key:r="message"}={}){var t,n={};for(t in e)n[t]="object"==typeof e[t]&&r in e[t]?e[t][r]:e[t];return n}};
|
|
6
|
+
module.exports={atomicWrite(e,r,t="utf8"){var n=require("path"),a=require("fs"),n=n.join(n.dirname(e),`.${n.basename(e)}.tmp`);a.writeFileSync(n,r,t),a.renameSync(n,e)},fetch(n){return"undefined"==typeof fetch?new Promise((t,e)=>{var r=n.match(/^([^:]+):\/\//)[1];/^https?$/.test(r)||e(new Error(app.msgs.error_invalidURL+".")),require(r).get(n,e=>{let r="";e.on("data",e=>r+=e),e.on("end",()=>t({json:()=>JSON.parse(r)}))}).on("error",e)}):fetch(n)},flatten(e,{key:r="message"}={}){var t,n={};for(t in e)n[t]="object"==typeof e[t]&&r in e[t]?e[t][r]:e[t];return n}};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* ยฉ 2024โ2026 Adam Lui & contributors under the MIT license.
|
|
3
|
+
* Source: https://github.com/adamlui/js-utils/tree/main/geolocate/src
|
|
4
|
+
* Documentation: https://github.com/adamlui/js-utils/tree/main/geolocate/docs
|
|
5
5
|
*/
|
|
6
|
-
|
|
6
|
+
let data=require(`./data${env.devMode?"":".min"}.js`),log=require(`./log${env.devMode?"":".min"}.js`);module.exports={generateRandomLang({includes:e=[],excludes:a=[]}={}){let t=require("fs"),s=require("path"),r=e.length?e:(()=>{var e=s.join(__dirname,"..",".cache"),a=s.join(e,"locales.json");if(t.existsSync(a))try{return JSON.parse(t.readFileSync(a,"utf8"))}catch(e){}var r=s.resolve(process.cwd(),"_locales");return t.existsSync(r)?(r=t.readdirSync(r,{withFileTypes:!0}).filter(e=>e.isDirectory()).map(e=>e.name).filter(e=>/^[a-z]{2}(?:_[A-Z]{2})?$/.test(e)),t.mkdirSync(e,{recursive:!0}),data.atomicWrite(a,JSON.stringify(r,null,2)),r):["en"]})(),n=new Set(a),l="en";return(r=r.filter(e=>!n.has(e))).length&&(l=r[Math.floor(Math.random()*r.length)]),log.debug(`
|
|
7
|
+
Random language: ${l}
|
|
8
|
+
`),l},async getMsgs(t="en"){let e=data.flatten(require(`../../${env.devMode?"../_locales/en/":"data/"}messages.json`),{key:"message"});if(!t.startsWith("en")){var s=`${app.urls.jsdelivr}@${app.commitHashes.locales}/${app.name.split("/")[1]}/_locales/`;let a=s+t.replace("-","_")+"/messages.json",r=0;for(;r<3;)try{log.debug(e=data.flatten(await(await data.fetch(a)).json(),{key:"message"}));break}catch(e){if(2<++r)break;a=t.includes("-")&&1==r?a.replace(/([^_]*)_[^/]*(\/.*)/,"$1$2"):s+"en/messages.json"}}return e},getSysLang(){var e;if("win32"!=process.platform)return((e=process.env).LANG||e.LANGUAGE||e.LC_ALL||e.LC_MESSAGES||e.LC_NAME||"en").split(".")[0];try{return require("child_process").execSync("(Get-Culture).TwoLetterISOLanguageName",{shell:"powershell",encoding:"utf-8"}).trim()}catch(e){return log.error("ERROR loading system language:",e.message),"en"}}};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ยฉ 2024โ2026 Adam Lui & contributors under the MIT license.
|
|
3
|
+
* Source: https://github.com/adamlui/js-utils/tree/main/geolocate/src
|
|
4
|
+
* Documentation: https://github.com/adamlui/js-utils/tree/main/geolocate/docs
|
|
5
|
+
*/
|
|
6
|
+
module.exports={colors:{nc:"[0m",br:"[1;91m",by:"[1;33m",bo:"[38;5;214m",bg:"[1;92m",bw:"[1;97m",blk:"[30m",tlBG:"[106m"},configURL(){this.info(`
|
|
7
|
+
${app.msgs.info_exampleValidConfigFile}: `+app.urls.config)},configURLandExit(...s){this.error(...s),this.configURL(),process.exit(1)},data(s){console.log(`
|
|
8
|
+
`+this.colors.bw+s+this.colors.nc)},debug(s){env.debugMode&&console.log(s)},error(...s){console.error(`
|
|
9
|
+
${this.colors.br}${app.msgs.prefix_error}:`,...s,this.colors.nc)},errorAndExit(...s){this.error(...s),this.helpCmdAndDocURL(),process.exit(1)},ifNotQuiet(s){app.config.quietMode||console.info(s)},info(s){console.info(`
|
|
10
|
+
`+this.colors.by+s+this.colors.nc)},tip(s){console.info(""+this.colors.by+app.msgs.prefix_tip+": "+s+this.colors.nc)},success(s){console.log(`
|
|
11
|
+
`+this.colors.bg+s+this.colors.nc)},warn(...s){console.warn(`
|
|
12
|
+
${this.colors.bo}${app.msgs.prefix_warning}:`,...s,this.colors.nc)},geoData(s){console.info([`
|
|
13
|
+
IP: `+this.colors.bw+s.ip+this.colors.nc,app.msgs.geoLabel_country+": "+this.colors.bw+s.country+this.colors.nc,app.msgs.geoLabel_region+": "+this.colors.bw+s.regionName+this.colors.nc,app.msgs.geoLabel_city+": "+this.colors.bw+s.city+this.colors.nc,app.msgs.geoLabel_zip+": "+this.colors.bw+s.zip+this.colors.nc,app.msgs.geoLabel_lat+": "+this.colors.bw+s.lat+this.colors.nc,app.msgs.geoLabel_lon+": "+this.colors.bw+s.lon+this.colors.nc,app.msgs.geoLabel_timeZone+": "+this.colors.bw+s.timezone.replace(/_/g," ").replace(/\//g," / ")+this.colors.nc,"ISP: "+this.colors.bw+s.isp+this.colors.nc].join("\n"))},help(s=["header","usage","params","flags","cmds"]){app.prefix=""+this.colors.tlBG+this.colors.blk+` ${app.name.replace(/^@[^/]+\//,"")} ${this.colors.nc} `;let o={header:[`
|
|
14
|
+
โ ${app.prefix}${app.msgs.appCopyright}.`,""+app.prefix+app.msgs.prefix_source+": "+app.urls.src],usage:[`
|
|
15
|
+
${this.colors.bw}o ${app.msgs.helpSection_usage}:`+this.colors.nc,` ${this.colors.bw}ยป `+this.colors.bg+app.cmdFormat+this.colors.nc],params:[`
|
|
16
|
+
${this.colors.bw}o ${app.msgs.helpSection_params}:`+this.colors.nc,` --config="path/to/file" ${app.msgs.optionDesc_config}.`],flags:[`
|
|
17
|
+
${this.colors.bw}o ${app.msgs.helpSection_flags}:`+this.colors.nc,` -q, --quiet ${app.msgs.optionDesc_quiet}.`],cmds:[`
|
|
18
|
+
${this.colors.bw}o ${app.msgs.helpSection_cmds}:`+this.colors.nc,` -i, --init ${app.msgs.optionDesc_init}.`,` -h, --help ${app.msgs.optionDesc_help}.`,` -v, --version ${app.msgs.optionDesc_version}.`]};s.forEach(c=>o[c]?.forEach(o=>{{var p=/header|usage/.test(c)?1:29;let e=process.stdout.columns||80,s=o.match(/\S+|\s+/g),i=[],r="";s.forEach(s=>{var o=e-(i.length?p:0);r.length+"| ".length+s.length>o&&(i.push(i.length?r.trimStart():r),r=""),r+=s}),i.push(i.length?r.trimStart():r),i.forEach((s,o)=>console.info("| "+(0==o?s:" ".repeat(p)+s)))}})),console.info(`
|
|
19
|
+
${app.msgs.info_moreHelp}, ${app.msgs.info_visit}: `+this.colors.bw+app.urls.docs+this.colors.nc)},helpCmdAndDocURL(){console.info(`
|
|
20
|
+
${app.msgs.info_moreHelp}, ${app.msgs.info_type} ${app.name.split("/")[1]} --help' ${app.msgs.info_or} ${app.msgs.info_visit}
|
|
21
|
+
`+this.colors.bw+app.urls.docs+this.colors.nc)},version(){var s=require("child_process").execSync(`npm view ${JSON.stringify(app.name)} version`).toString().trim()||"none";let o="none";try{var e=require("path").resolve(process.cwd(),"node_modules",app.name,"package.json");require("fs").existsSync(e)&&(o=require(e).version||"none")}catch(s){this.error(app.msgs.error_readingLocalPkgVer+":",s.message)}console.info(`
|
|
22
|
+
${app.msgs.prefix_globalVer}: ${s}
|
|
23
|
+
${app.msgs.prefix_localVer}: `+o)}};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ยฉ 2024โ2026 Adam Lui & contributors under the MIT license.
|
|
3
|
+
* Source: https://github.com/adamlui/js-utils/tree/main/geolocate/src
|
|
4
|
+
* Documentation: https://github.com/adamlui/js-utils/tree/main/geolocate/docs
|
|
5
|
+
*/
|
|
6
|
+
let fs=require("fs"),log=require(`./log${env.devMode?"":".min"}.js`),path=require("path");(globalThis.app??={}).config={},module.exports={configFilename:"geolocate.config.mjs",controls:{config:{type:"param",regex:/^--?config(?:=.*|$)/},quietMode:{type:"flag",regex:/^--?q(?:uiet)?(?:-?mode)?$/},init:{type:"cmd",regex:/^-{0,2}i(?:nit)?$/},help:{type:"cmd",regex:/^--?h(?:elp)?$/},version:{type:"cmd",regex:/^--?ve?r?s?i?o?n?$/}},async initConfigFile(o=this.configFilename){var e=path.resolve(process.cwd(),o);if(fs.existsSync(e))return log.warn(app.msgs.warn_configFileExists+":",e);var i=path.resolve(__dirname,"../../"+(env.devMode?"../":"./data/")+o);if(fs.existsSync(i))fs.copyFileSync(i,e);else{i=require(`./data${env.devMode?"":".min"}.js`),o=app.urls.jsdelivr+"/geolocate/"+o;log.data(app.msgs.info_fetchingRemoteConfigFrom+` ${o}...`);try{var s=await i.fetch(o);if(!s.ok)return log.warn(`${app.msgs.warn_remoteConfigNotFound}: ${o} (${s.status})`);i.atomicWrite(e,await s.text())}catch(e){return log.warn(app.msgs.warn_remoteConfigFailed+`: ${o} `+e.message)}}log.success(app.msgs.info_configFileCreated+`: ${e}
|
|
7
|
+
`),log.tip(app.msgs.tip_editToSetDefaults+"."),log.tip(app.msgs.tip_cliArgsPrioritized+".")},load({args:e=process.argv.slice(2),ctrlKeys:r=Object.keys(this.controls)}={}){r.forEach(e=>{var o=this.controls[e];o.mode||"cmd"==o.type||(app.config[e]??=o.defaultVal??("flag"!=o.type&&""))});let o;var i=e.find(e=>this.controls.config.regex.test(e));if(i){/=/.test(i)||log.errorAndExit(`[${i}] `+app.msgs.error_mustIncludePath);i=i.split("=")[1];o=path.isAbsolute(i)?i:path.resolve(process.cwd(),i),fs.existsSync(o)||log.configURLandExit(app.msgs.error_configFileNotFound+":",o)}else for(var s of["mjs","cjs","js"]){s=path.resolve(process.cwd(),this.configFilename.replace(/\.[^.]+$/,"."+s));if(fs.existsSync(s)){o=s;break}}if(o)try{var t=require(o),a=t?.default??t;a&&"object"==typeof a||log.configURLandExit(app.msgs.error_invalidConfigFile+"."),Object.assign(app.config,a)}catch(e){log.configURLandExit(app.msgs.error_failedToLoadConfigFile+":",o,`
|
|
8
|
+
`+e.message)}return e.forEach(o=>{if(!/^[^-]|--?(?:config|debug)/.test(o)){var i=r.find(e=>this.controls[e]?.regex?.test(o)),s=(i||log.errorAndExit(`[${o}] ${app.msgs.error_notRecognized}.`),this.controls[i]);if("cmd"!=s.type){let e="param"!=s.type||o.split("=")[1]?.trim();s.mode?app.config.mode=i.replace(/mode$/i,"").toLowerCase():((s=s.parser)&&(e=s(e),isNaN(e)||e<1)&&log.errorAndExit(`[${i}] ${app.msgs.error_nonPositiveNum}.`),app.config[i]=e)}}}),app.config}};
|
package/dist/data/app.json
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
"copyrightYear": "2024โ2026",
|
|
6
6
|
"cmdFormat": "geolocate [ip1] [ip2] [...] [options|commands]",
|
|
7
7
|
"urls": {
|
|
8
|
+
"config": "https://github.com/adamlui/js-utils/blob/main/geolocate/geolocate-ip.config.mjs",
|
|
8
9
|
"docs": "https://github.com/adamlui/js-utils/tree/main/geolocate/docs",
|
|
9
10
|
"github": "https://github.com/adamlui/js-utils",
|
|
10
11
|
"jsdelivr": "https://cdn.jsdelivr.net/gh/adamlui/js-utils",
|
|
@@ -12,6 +13,6 @@
|
|
|
12
13
|
"src": "https://github.com/adamlui/js-utils/tree/main/geolocate/src"
|
|
13
14
|
},
|
|
14
15
|
"commitHashes": {
|
|
15
|
-
"locales": "
|
|
16
|
+
"locales": "171f054"
|
|
16
17
|
}
|
|
17
18
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* geolocate.config.mjs
|
|
3
|
+
*
|
|
4
|
+
* Optional config file for the geolocate CLI.
|
|
5
|
+
* Copy this file to your project root to set default options.
|
|
6
|
+
* CLI arguments always override these values.
|
|
7
|
+
*
|
|
8
|
+
* Docs: https://github.com/adamlui/js-utils/tree/main/geolocate/#-command-line-usage
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export default {
|
|
12
|
+
quietMode: false // suppress all logging except errors
|
|
13
|
+
}
|
package/dist/data/messages.json
CHANGED
|
@@ -2,15 +2,32 @@
|
|
|
2
2
|
"appName": { "message": "geolocate" },
|
|
3
3
|
"appCopyright": { "message": "ยฉ 2024โ2026 Adam Lui under the MIT license" },
|
|
4
4
|
"prefix_error": { "message": "ERROR" },
|
|
5
|
+
"prefix_tip": { "message": "TIP" },
|
|
6
|
+
"prefix_warning": { "message": "WARNING" },
|
|
5
7
|
"prefix_globalVer": { "message": "Global version" },
|
|
6
8
|
"prefix_localVer": { "message": "Local version" },
|
|
7
9
|
"prefix_source": { "message": "Source" },
|
|
10
|
+
"error_readingLocalPkgVer": { "message": "Error reading local package version" },
|
|
8
11
|
"error_notRecognized": { "message": "not recognized" },
|
|
12
|
+
"error_nonPositiveNum": { "message": "argument can only be > 0" },
|
|
9
13
|
"error_invalidURL": { "message": "Invalid URL" },
|
|
10
|
-
"
|
|
11
|
-
"
|
|
14
|
+
"error_invalidConfigFile": { "message": "Config file must export an object" },
|
|
15
|
+
"error_configFileNotFound": { "message": "Config file not found" },
|
|
16
|
+
"error_failedToLoadConfigFile": { "message": "Failed to load config file" },
|
|
17
|
+
"error_mustIncludePath": { "message": "must include =path" },
|
|
18
|
+
"warn_configFileExists": { "message": "Config file already exists" },
|
|
19
|
+
"info_exampleValidConfigFile": { "message": "Example valid config file" },
|
|
20
|
+
"info_copyingToClip": { "message": "Copying to clipboard" },
|
|
12
21
|
"info_moreHelp": { "message": "For more help" },
|
|
22
|
+
"info_type": { "message": "type" },
|
|
23
|
+
"info_or": { "message": "or" },
|
|
13
24
|
"info_visit": { "message": "visit" },
|
|
25
|
+
"info_configFileCreated": { "message": "Config file created" },
|
|
26
|
+
"info_fetchingRemoteConfigFrom": { "message": "Fetching remote config file from" },
|
|
27
|
+
"warn_remoteConfigNotFound": { "message": "Remote config file not found" },
|
|
28
|
+
"warn_remoteConfigFailed": { "message": "Failed to fetch remote config file" },
|
|
29
|
+
"tip_editToSetDefaults": { "message": "Edit this file to customize defaults" },
|
|
30
|
+
"tip_cliArgsPrioritized": { "message": "CLI arguments always override these values" },
|
|
14
31
|
"geoLabel_country": { "message": "Country" },
|
|
15
32
|
"geoLabel_region": { "message": "Region" },
|
|
16
33
|
"geoLabel_city": { "message": "City" },
|
|
@@ -19,9 +36,12 @@
|
|
|
19
36
|
"geoLabel_lon": { "message": "Longitude" },
|
|
20
37
|
"geoLabel_timeZone": { "message": "Time zone" },
|
|
21
38
|
"helpSection_usage": { "message": "Usage" },
|
|
22
|
-
"
|
|
23
|
-
"
|
|
39
|
+
"helpSection_params": { "message": "Parameter options" },
|
|
40
|
+
"helpSection_flags": { "message": "Config options" },
|
|
41
|
+
"helpSection_cmds": { "message": "Commands" },
|
|
42
|
+
"optionDesc_config": { "message": "Load custom config file" },
|
|
24
43
|
"optionDesc_quiet": { "message": "Suppress all logging except errors" },
|
|
44
|
+
"optionDesc_init": { "message": "Create config file (in project root)" },
|
|
25
45
|
"optionDesc_help": { "message": "Display help screen" },
|
|
26
46
|
"optionDesc_version": { "message": "Show version number" }
|
|
27
47
|
}
|
package/dist/geolocate.min.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* ยฉ 2024โ2026 Adam Lui & contributors under the MIT license.
|
|
3
|
+
* Source: https://github.com/adamlui/js-utils/tree/main/geolocate/src
|
|
4
|
+
* Documentation: https://github.com/adamlui/js-utils/tree/main/geolocate/docs
|
|
5
5
|
*/
|
|
6
|
-
async function geolocate(e,n={}){
|
|
6
|
+
async function geolocate(e,n={}){var t,o={verbose:!0};log.prefix="geolocate()",(e=[].concat(e))[0]||=await getOwnIP();for(t of e){n.verbose&&log.info(`Validating ${t}...`);let o;try{o=require("generate-ip").ipv4.validate}catch(e){await import("https://cdn.jsdelivr.net/npm/generate-ip/dist/generate-ip.min.js"),o=window.ipv4.validate}if(o&&!o(t,{verbose:!1}))return log.error(t+" is not a valid IPv4 address.")}if(validateOptions({options:n,defaultOptions:o,helpURL:"https://github.com/adamlui/js-utils/tree/main/geolocate/docs/#locateips-options",exampleCall:"geolocate('8.8.8.8', { verbose: false })"})){n={...o,...n};try{var l,s=[];for(l of e){n.verbose&&log.info(`Fetching geolocation data for ${l}...`);let e=await fetchData("http://ip-api.com/json/"+l),{status:o,org:t,as:r,query:a,...i}=await e.json();s.push({ip:l,...i})}return n.verbose&&"undefined"!=typeof window&&log.info("Success!","Check returned array."),s}catch(e){log.error(e.message)}}}function fetchData(r){return"undefined"==typeof fetch?new Promise((t,o)=>{try{var e=r.match(/^([^:]+):\/\//)[1];/^https?$/.test(e)||o(new Error("Invalid fetchData() URL.")),require(e).get(r,e=>{let o="";e.on("data",e=>o+=e),e.on("end",()=>t({json:()=>JSON.parse(o)}))}).on("error",e=>o(new Error(e.message)))}catch(e){o(new Error("Environment not supported."))}}):fetch(r)}async function getOwnIP(){return fetchData("https://ifconfig.me/ip").then(e=>e.text()).catch(()=>fetchData("http://ip-api.com/json/").then(e=>e.json()).then(e=>e.query)).catch(async()=>{try{var e=require("child_process").exec,o=require("util").promisify,{stdout:t,stderr:r}=await o(e)("curl -s ifconfig.me");return r?log.error(r):t.trim()}catch(e){log.error(e.message)}})}function validateOptions({options:e,defaultOptions:o,helpURL:t,exampleCall:r}){var a,i,n=Object.keys(o).filter(e=>"boolean"==typeof o[e]),l=Object.keys(o).filter(e=>Number.isInteger(o[e]));if("object"!=typeof e)return a=r.split(",").findIndex(e=>e.trim().startsWith("{"))+1,a+=["st","nd","rd"][a-1]||"th",log.error(`${"0th"==a?"[O":a+" arg [o"}ptions] can only be an object of key/vals.`),log.info("Example valid call:",r),log.validOptions(o),log.helpURL(t),!1;for(i in e){if(!Object.prototype.hasOwnProperty.call(o,i))return log.error(`\`${i}\` is an invalid option.`),log.validOptions(o),log.helpURL(t),!1;if(n.includes(i)&&"boolean"!=typeof e[i])return log.error(`[${i}] option can only be \`true\` or \`false\`.`),log.helpURL(t),!1;if(l.includes(i)&&(e[i]=parseInt(e[i],10),isNaN(e[i])||e[i]<1))return log.error(`[${i}] option can only be an integer > 0.`),log.helpURL(t),!1}return!0}Object.assign(globalThis.app??={},{name:"geolocate",aliases:{geolocate:["Geolocate","geoLocate","GeoLocate","locate","Locate"]}});let log={prefix:app.name,error(...e){console.error(this.prefix+" ยป ERROR:",...e)},helpURL(e=app.urls?.docs){this.info("For more help, please visit",e)},info(...e){console.info(this.prefix+" ยป",...e)},validOptions(e){var o=Object.keys(e).join(", "),e=JSON.stringify(e,void 0,2).replace(/"([^"]+)":/g,"$1:").replace(/"/g,"'").replace(/\n\s*/g," ");this.info(`Valid options: [${o}]`),this.info("If omitted, default settings are: "+e)}};try{module.exports={geolocate:geolocate}}catch(e){}try{window.geo={geolocate:geolocate}}catch(e){}for(let o in app.aliases){try{app.aliases[o].forEach(e=>module.exports[e]??=module.exports[o])}catch(e){}try{app.aliases[o].forEach(e=>window.geo[e]??=window.geo[o])}catch(e){}}
|
package/docs/README.md
CHANGED
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
<img height=31 src="https://img.shields.io/npm/dm/@adamlui/geolocate?logo=npm&color=af68ff&logoColor=white&labelColor=464646&style=for-the-badge"></a>
|
|
9
9
|
<a href="#%EF%B8%8F-mit-license">
|
|
10
10
|
<img height=31 src="https://img.shields.io/badge/License-MIT-orange.svg?logo=internetarchive&logoColor=white&labelColor=464646&style=for-the-badge"></a>
|
|
11
|
-
<a href="https://github.com/adamlui/js-utils/releases/tag/geolocate-2.0
|
|
12
|
-
<img height=31 src="https://img.shields.io/badge/Latest_Build-2.0
|
|
11
|
+
<a href="https://github.com/adamlui/js-utils/releases/tag/geolocate-2.1.0">
|
|
12
|
+
<img height=31 src="https://img.shields.io/badge/Latest_Build-2.1.0-44cc11.svg?logo=icinga&logoColor=white&labelColor=464646&style=for-the-badge"></a>
|
|
13
13
|
<a href="https://www.npmjs.com/package/@adamlui/geolocate?activeTab=code">
|
|
14
14
|
<img height=31 src="https://img.shields.io/npm/unpacked-size/%40adamlui%2Fgeolocate?style=for-the-badge&logo=ebox&logoColor=white&labelColor=464646&color=blue"></a>
|
|
15
|
-
<a href="https://github.com/adamlui/js-utils/blob/geolocate-2.0
|
|
16
|
-
<img height=31 src="https://img.shields.io/github/size/adamlui/js-utils/geolocate/dist/geolocate.min.js?branch=geolocate-2.0
|
|
15
|
+
<a href="https://github.com/adamlui/js-utils/blob/geolocate-2.1.0/geolocate/dist/geolocate.min.js">
|
|
16
|
+
<img height=31 src="https://img.shields.io/github/size/adamlui/js-utils/geolocate/dist/geolocate.min.js?branch=geolocate-2.1.0&label=Minified%20Size&logo=databricks&logoColor=white&labelColor=464646&color=ff69b4&style=for-the-badge"></a>
|
|
17
17
|
<a href="https://sonarcloud.io/component_measures?metric=new_vulnerabilities&id=adamlui_js-utils:geolocate/src/geolocate.js">
|
|
18
18
|
<img height=31 src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fsonarcloud.io%2Fapi%2Fmeasures%2Fcomponent%3Fcomponent%3Dadamlui_js-utils%3Ageolocate%2Fsrc%2Fgeolocate.js%26metricKeys%3Dvulnerabilities&query=%24.component.measures.0.value&style=for-the-badge&logo=sonarcloud&logoColor=white&labelColor=464646&label=Vulnerabilities&color=gold"></a>
|
|
19
19
|
<a href="https://github.com/toolleeo/cli-apps#networking">
|
|
@@ -66,14 +66,34 @@ Sample output:
|
|
|
66
66
|
### Command line options
|
|
67
67
|
|
|
68
68
|
```
|
|
69
|
+
Parameter options:
|
|
70
|
+
--config="path/to/file" Load custom config file.
|
|
71
|
+
|
|
69
72
|
Boolean options:
|
|
70
73
|
-q, --quiet Suppress all logging except errors.
|
|
71
74
|
|
|
72
|
-
|
|
75
|
+
Commands:
|
|
76
|
+
-i, --init Create config file (in project root).
|
|
73
77
|
-h, --help Display help screen.
|
|
74
78
|
-v, --version Show version number.
|
|
75
79
|
```
|
|
76
80
|
|
|
81
|
+
#
|
|
82
|
+
|
|
83
|
+
### Configuration file
|
|
84
|
+
|
|
85
|
+
**generate-ip** can be customized using a `geolocate.config.mjs` or `geolocate.config.js` placed in your project root.
|
|
86
|
+
|
|
87
|
+
Example defaults:
|
|
88
|
+
|
|
89
|
+
```js
|
|
90
|
+
export default {
|
|
91
|
+
quietMode: false // suppress all logging except errors
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
๐ก Run `geolocate init` to generate a template `geolocate.config.mjs` in your project root.
|
|
96
|
+
|
|
77
97
|
<br>
|
|
78
98
|
|
|
79
99
|
<img height=6px width="100%" src="https://assets.js-utils.org/images/separators/aqua-gradient.png?v=0d36e26">
|
|
@@ -87,7 +107,7 @@ You can also import **geolocate** into your app to use its main API method.
|
|
|
87
107
|
#### ECMAScript*:
|
|
88
108
|
|
|
89
109
|
```js
|
|
90
|
-
import geo from '@adamlui/geolocate'
|
|
110
|
+
import geo from '@adamlui/geolocate'
|
|
91
111
|
```
|
|
92
112
|
|
|
93
113
|
#### CommonJS:
|
|
@@ -103,14 +123,14 @@ const geo = require('@adamlui/geolocate')
|
|
|
103
123
|
#### <> HTML script tag:
|
|
104
124
|
|
|
105
125
|
```html
|
|
106
|
-
<script src="https://cdn.jsdelivr.net/npm/@adamlui/geolocate@2.0
|
|
126
|
+
<script src="https://cdn.jsdelivr.net/npm/@adamlui/geolocate@2.1.0/dist/geolocate.min.js"></script>
|
|
107
127
|
```
|
|
108
128
|
|
|
109
129
|
#### ES6:
|
|
110
130
|
|
|
111
131
|
```js
|
|
112
132
|
(async () => {
|
|
113
|
-
await import('https://cdn.jsdelivr.net/npm/@adamlui/geolocate@2.0
|
|
133
|
+
await import('https://cdn.jsdelivr.net/npm/@adamlui/geolocate@2.1.0/dist/geolocate.min.js')
|
|
114
134
|
// Your code here...
|
|
115
135
|
})()
|
|
116
136
|
```
|
|
@@ -119,7 +139,7 @@ const geo = require('@adamlui/geolocate')
|
|
|
119
139
|
|
|
120
140
|
```js
|
|
121
141
|
...
|
|
122
|
-
// @require https://cdn.jsdelivr.net/npm/@adamlui/geolocate@2.0
|
|
142
|
+
// @require https://cdn.jsdelivr.net/npm/@adamlui/geolocate@2.1.0/dist/geolocate.min.js
|
|
123
143
|
// ==/UserScript==
|
|
124
144
|
|
|
125
145
|
// Your code here...
|
|
@@ -127,7 +147,7 @@ const geo = require('@adamlui/geolocate')
|
|
|
127
147
|
|
|
128
148
|
<br>
|
|
129
149
|
|
|
130
|
-
**๐ Note:** To always import the latest version (not recommended in production!) remove the `@2.0
|
|
150
|
+
**๐ Note:** To always import the latest version (not recommended in production!) remove the `@2.1.0` version tag from the jsDelivr URL: `https://cdn.jsdelivr.net/npm/@adamlui/geolocate/dist/geolocate.min.js`
|
|
131
151
|
|
|
132
152
|
<br>
|
|
133
153
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adamlui/geolocate",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Fetch IP geolocation data from the CLI.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Adam Lui",
|
|
@@ -40,7 +40,12 @@
|
|
|
40
40
|
"doc": "./docs"
|
|
41
41
|
},
|
|
42
42
|
"scripts": {
|
|
43
|
-
"build": "
|
|
43
|
+
"build": "node utils/build",
|
|
44
|
+
"build:js": "node utils/build --js",
|
|
45
|
+
"build:data": "node utils/build --data",
|
|
46
|
+
"build:json": "node utils/build --json",
|
|
47
|
+
"debug": "node src/cli --debug",
|
|
48
|
+
"translate": "py utils/translate-en-messages.py",
|
|
44
49
|
"bump:patch": "bash utils/bump.sh patch",
|
|
45
50
|
"bump:minor": "bash utils/bump.sh minor",
|
|
46
51
|
"bump:major": "bash utils/bump.sh major"
|
|
@@ -61,10 +66,10 @@
|
|
|
61
66
|
"url": "https://github.com/adamlui/js-utils/issues"
|
|
62
67
|
},
|
|
63
68
|
"dependencies": {
|
|
64
|
-
"generate-ip": "^2.4.7",
|
|
65
69
|
"node-clipboardy": "^1.0.3"
|
|
66
70
|
},
|
|
67
71
|
"devDependencies": {
|
|
68
|
-
"@adamlui/minify.js": "^2.
|
|
72
|
+
"@adamlui/minify.js": "^2.2.0",
|
|
73
|
+
"generate-ip": "^2.5.0"
|
|
69
74
|
}
|
|
70
75
|
}
|