generate-pw 2.1.0 → 2.1.2

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 CHANGED
@@ -25,12 +25,12 @@
25
25
  <img height=31 src="https://img.shields.io/npm/dm/generate-pw?logo=npm&color=af68ff&logoColor=white&labelColor=464646&style=for-the-badge"></a>
26
26
  <a href="#%EF%B8%8F-mit-license">
27
27
  <img height=31 src="https://img.shields.io/badge/License-MIT-orange.svg?logo=internetarchive&logoColor=white&labelColor=464646&style=for-the-badge"></a>
28
- <a href="https://github.com/adamlui/js-utils/releases/tag/generate-pw-2.1.0">
29
- <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>
28
+ <a href="https://github.com/adamlui/js-utils/releases/tag/generate-pw-2.1.2">
29
+ <img height=31 src="https://img.shields.io/badge/Latest_Build-2.1.2-44cc11.svg?logo=icinga&logoColor=white&labelColor=464646&style=for-the-badge"></a>
30
30
  <a href="https://www.npmjs.com/package/generate-pw?activeTab=code">
31
31
  <img height=31 src="https://img.shields.io/npm/unpacked-size/generate-pw?style=for-the-badge&logo=ebox&logoColor=white&labelColor=464646&color=blue"></a>
32
- <a href="https://github.com/adamlui/js-utils/blob/generate-pw-2.1.0/generate-pw/dist/generate-pw.min.js">
33
- <img height=31 src="https://img.shields.io/github/size/adamlui/js-utils/generate-pw/dist/generate-pw.min.js?branch=generate-pw-2.1.0&label=Minified%20Size&logo=databricks&logoColor=white&labelColor=464646&color=ff69b4&style=for-the-badge"></a>
32
+ <a href="https://github.com/adamlui/js-utils/blob/generate-pw-2.1.2/generate-pw/dist/generate-pw.min.js">
33
+ <img height=31 src="https://img.shields.io/github/size/adamlui/js-utils/generate-pw/dist/generate-pw.min.js?branch=generate-pw-2.1.2&label=Minified%20Size&logo=databricks&logoColor=white&labelColor=464646&color=ff69b4&style=for-the-badge"></a>
34
34
  <a href="https://sonarcloud.io/component_measures?metric=new_vulnerabilities&id=adamlui_js-utils:generate-pw/src/generate-pw.js">
35
35
  <img height=31 src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fsonarcloud.io%2Fapi%2Fmeasures%2Fcomponent%3Fcomponent%3Dadamlui_js-utils%3Agenerate-pw%2Fsrc%2Fgenerate-pw.js%26metricKeys%3Dvulnerabilities&query=%24.component.measures.0.value&style=for-the-badge&logo=sonarcloud&logoColor=white&labelColor=464646&label=Vulnerabilities&color=gold"></a>
36
36
  <a href="https://github.com/toolleeo/cli-apps#password-managers">
@@ -94,14 +94,14 @@ const pw = require('generate-pw')
94
94
  #### <> HTML script tag:
95
95
 
96
96
  ```html
97
- <script src="https://cdn.jsdelivr.net/npm/generate-pw@2.1.0/dist/generate-pw.min.js"></script>
97
+ <script src="https://cdn.jsdelivr.net/npm/generate-pw@2.1.2/dist/generate-pw.min.js"></script>
98
98
  ```
99
99
 
100
100
  #### ES6:
101
101
 
102
102
  ```js
103
103
  (async () => {
104
- await import('https://cdn.jsdelivr.net/npm/generate-pw@2.1.0/dist/generate-pw.min.js')
104
+ await import('https://cdn.jsdelivr.net/npm/generate-pw@2.1.2/dist/generate-pw.min.js')
105
105
  // Your code here...
106
106
  })()
107
107
  ```
@@ -110,7 +110,7 @@ const pw = require('generate-pw')
110
110
 
111
111
  ```js
112
112
  ...
113
- // @require https://cdn.jsdelivr.net/npm/generate-pw@2.1.0/dist/generate-pw.min.js
113
+ // @require https://cdn.jsdelivr.net/npm/generate-pw@2.1.2/dist/generate-pw.min.js
114
114
  // ==/UserScript==
115
115
 
116
116
  // Your code here...
@@ -118,7 +118,7 @@ const pw = require('generate-pw')
118
118
 
119
119
  <br>
120
120
 
121
- **💡 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/generate-pw/dist/generate-pw.min.js`
121
+ **💡 Note:** To always import the latest version (not recommended in production!) remove the `@2.1.2` version tag from the jsDelivr URL: `https://cdn.jsdelivr.net/npm/generate-pw/dist/generate-pw.min.js`
122
122
 
123
123
  <br>
124
124
 
@@ -4,5 +4,5 @@
4
4
  * Source: https://github.com/adamlui/js-utils/tree/main/generate-pw/src
5
5
  * Documentation: https://github.com/adamlui/js-utils/tree/main/generate-pw/docs
6
6
  */
7
- (async()=>{globalThis.env={args:process.argv.slice(2),devMode:/[\\/]src(?:[\\/]|$)/i.test(__dirname)},env.debugMode=env.args.some(e=>/^--?debug(?:-?mode)?$/.test(e));var e,i=require("node-clipboardy"),c=require(`../generate-pw${env.devMode?"":".min"}.js`).generatePassword,n=require(`./lib/language${env.devMode?"":".min"}.js`),o=require(`./lib/log${env.devMode?"":".min"}.js`),l=require(`./lib/settings${env.devMode?"":".min"}.js`);Object.assign(globalThis.cli??={},require(`../${env.devMode?"../":"data/"}package-data.json`)),l.load("uiLang"),cli.lang=cli.config.uiLang||(env.debugMode?n.generateRandomLang({excludes:["en"]}):n.getSysLang()),cli.msgs=await n.getMsgs(cli.lang),cli.lang.startsWith("en")?cli.urls.docs+="/#-command-line-usage":(cli.docLocale=cli.lang.replace("_","-").toLowerCase(),(await n.getDocLocales()).includes(cli.docLocale)&&o.debug(cli.urls.docs+=`/${cli.docLocale}#readme`));for(e of env.args){if(l.controls.init.regex.test(e))return l.initConfigFile();if(l.controls.help.regex.test(e))return o.help();if(l.controls.version.regex.test(e))return o.version()}l.load();n={length:cli.config.length,qty:cli.config.qty,strength:cli.config.mode,charset:cli.config.charset,exclude:cli.config.excludeChars,numbers:!cli.config.excludeNums,symbols:!cli.config.excludeSymbols,lowercase:!cli.config.excludeLowerChars,uppercase:!cli.config.excludeUpperChars,similarChars:cli.config.similarChars,strict:!cli.config.unstrict,entropy:cli.config.entropy,verbose:!cli.config.quietMode};i.writeSync([].concat(c(n)).join("\n")),o.ifNotQuiet(`
8
- ${cli.msgs.info_copyingToClip}...`)})();
7
+ (async()=>{globalThis.env={args:process.argv.slice(2),devMode:/[\\/]src(?:[\\/]|$)/i.test(__dirname)},env.debugMode=env.args.some(e=>/^--?debug(?:-?mode)?$/.test(e)),env.modExt=`${env.devMode?"":".min"}.js`;var e=require("node-clipboardy"),i=require("../generate-pw"+env.modExt).generatePassword,c=require("./lib/init"+env.modExt),o=require("./lib/log"+env.modExt);return await c.cli(),cli.config.init?c.configFile():cli.config.help?o.help():cli.config.version?o.version():(c={length:cli.config.length,qty:cli.config.qty,strength:cli.config.mode,charset:cli.config.charset,exclude:cli.config.excludeChars,numbers:!cli.config.excludeNums,symbols:!cli.config.excludeSymbols,lowercase:!cli.config.excludeLowerChars,uppercase:!cli.config.excludeUpperChars,similarChars:cli.config.similarChars,strict:!cli.config.unstrict,entropy:cli.config.entropy,verbose:!cli.config.quietMode},e.writeSync([].concat(i(c)).join("\n")),void o.ifNotQuiet(`
8
+ ${cli.msgs.info_copyingToClip}...`))})();
@@ -0,0 +1,6 @@
1
+ /**
2
+ * © 2024–2026 Adam Lui & contributors under the MIT license.
3
+ * Source: https://github.com/adamlui/js-utils/tree/main/generate-pw/src
4
+ * Documentation: https://github.com/adamlui/js-utils/tree/main/generate-pw/docs
5
+ */
6
+ let language=require("./language"+env.modExt),log=require("./log"+env.modExt),settings=require("./settings"+env.modExt),dataPath="../../"+(env.devMode?"../":"data/");module.exports={async cli(){Object.assign(globalThis.cli??={},require(dataPath+"package-data.json")),cli.lang=settings.load("uiLang")||(env.debugMode?language.generateRandomLang({excludes:["en"]}):language.getSysLang()),cli.msgs=await language.getMsgs(cli.lang),cli.urls.cliDocs=cli.urls.docs+"/#-command-line-usage",cli.lang.startsWith("en")||(cli.docLocale=cli.lang.replace("_","-").toLowerCase(),cli.docLocales??=await language.getDocLocales(),cli.docLocales?.includes(cli.docLocale)&&log.debug(cli.urls.cliDocs=cli.urls.docs+`/${cli.docLocale}#readme`)),settings.load()},async configFile(e=settings.configFilename){var a=require("fs"),i=require("path"),t={target:i.resolve(process.cwd(),e)};if(a.existsSync(t.target))return log.warn(cli.msgs.warn_configFileExists+":",t.target);if(a.existsSync(t.src=i.resolve(__dirname,""+dataPath+e)))a.copyFileSync(t.src,t.target);else{i=require("./jsdelivr"+env.modExt).pkgVerURL+`/${e}/`;log.data(cli.msgs.info_fetchingRemoteConfigFrom+` ${i}...`);try{var l=require("./data"+env.modExt),s=await l.fetch(i);if(!s.ok)return log.warn(`${cli.msgs.warn_remoteConfigNotFound}: ${i} (${s.status})`);l.atomicWrite(t.target,await s.text())}catch(e){return log.warn(cli.msgs.warn_remoteConfigFailed+`: ${i} `+e.message)}}log.success(`${cli.msgs.info_configFileCreated}: ${t.target}\n`),log.tip(cli.msgs.tip_editToSetDefaults+"."),log.tip(cli.msgs.tip_cliArgsPrioritized+".")}};
@@ -0,0 +1,6 @@
1
+ /**
2
+ * © 2024–2026 Adam Lui & contributors under the MIT license.
3
+ * Source: https://github.com/adamlui/js-utils/tree/main/generate-pw/src
4
+ * Documentation: https://github.com/adamlui/js-utils/tree/main/generate-pw/docs
5
+ */
6
+ module.exports={pkgVerURL(e){e||=cli.version||=require("./pkg"+env.modExt).getVer("local")||"none";e=/^\d+\.\d+\.\d+$/.test(e)?cli.name+"-"+e:"latest";return cli.urls.jsdelivr+`@${e}/`+cli.name},commitURL(e="latest"){return cli.urls.jsdelivr+`@${e}/`+cli.name}};
@@ -3,5 +3,5 @@
3
3
  * Source: https://github.com/adamlui/js-utils/tree/main/generate-pw/src
4
4
  * Documentation: https://github.com/adamlui/js-utils/tree/main/generate-pw/docs
5
5
  */
6
- let data=require(`./data${env.devMode?"":".min"}.js`),log=require(`./log${env.devMode?"":".min"}.js`);module.exports={formatCode(e){return e.replace(/([a-z]{2,8})[-_]([a-z]{2})/i,(e,r,a)=>r.toLowerCase()+"_"+a.toUpperCase())},async getDocLocales(){cli.version??=require(`./pkg${env.devMode?"":".min"}.js`).getVer("local");var e=cli.version?cli.name+"-"+cli.version:"latest",e=cli.urls.jsdelivr+`@${e}/${cli.name}/docs/`,r=[];try{for(var a,t=await(await data.fetch(e)).text(),s=/href=".*\/docs\/([^/]+)\/"/g;a=s.exec(t);)r.push(a[1])}catch(e){log.warn(cli.msgs.warn_docLocalesFetchFailed+":",e.message)}return r},generateRandomLang({includes:e=[],excludes:r=[]}={}){let t=require("fs"),s=require("path"),a=e.length?e:(()=>{var e=s.join(__dirname,"..",".cache"),r=s.join(e,"locales.json");if(t.existsSync(r))try{return JSON.parse(t.readFileSync(r,"utf8"))}catch(e){}var a=s.resolve(process.cwd(),"_locales");return t.existsSync(a)?(a=t.readdirSync(a,{withFileTypes:!0}).filter(e=>e.isDirectory()).map(e=>e.name).filter(e=>/^\w{2}[-_]?\w{0,2}$/.test(e)),t.mkdirSync(e,{recursive:!0}),data.atomicWrite(r,JSON.stringify(a,null,2)),a):["en"]})(),l=new Set(r),n="en";return(a=a.filter(e=>!l.has(e))).length&&(n=a[Math.floor(Math.random()*a.length)]),log.debug(`Random language: ${n}
7
- `),n},async getMsgs(t="en"){t=module.exports.formatCode(t);let e=data.flatten(require(`../../${env.devMode?"../_locales/en/":"data/"}messages.json`));if(!t.startsWith("en")){var s=`${cli.urls.jsdelivr}@${cli.commitHashes.locales}/${cli.name}/_locales/`;let r=s+t+"/messages.json",a=0;for(;a<3;)try{e=data.flatten(await(await data.fetch(r)).json());break}catch(e){if(3<=++a)break;log.debug(r=t.includes("-")&&1==a?r.replace(/([^_]*)_[^/]*(\/.*)/,"$1$2"):s+"en/messages.json")}}return e},getSysLang(){try{var e;return"win32"==process.platform?require("child_process").execSync("(Get-Culture).TwoLetterISOLanguageName",{shell:"powershell",encoding:"utf-8"}).trim():((e=process.env).LANG||e.LANGUAGE||e.LC_ALL||e.LC_MESSAGES||e.LC_NAME).split(".")[0]}catch(e){return log.error(cli.msgs.error_failedToFetchSysLang+":",e.message),"en"}}};
6
+ let data=require("./data"+env.modExt),log=require("./log"+env.modExt);module.exports={formatCode(e){return e.replace(/([a-z]{2,8})[-_]([a-z]{2})/i,(e,r,a)=>r.toLowerCase()+"_"+a.toUpperCase())},async getDocLocales(){cli.version||=require("./pkg"+env.modExt).getVer("local")||"none";var e=require("./jsdelivr"+env.modExt).pkgVerURL()+"/docs/",r=[];try{for(var a,t=await(await data.fetch(e)).text(),s=/href=".*\/docs\/([^/]+)\/"/g;a=s.exec(t);)r.push(a[1])}catch(e){log.warn(cli.msgs.warn_docLocalesFetchFailed+":",e.message)}return r},generateRandomLang({includes:e=[],excludes:r=[]}={}){let t=require("fs"),s=require("path"),a=e.length?e:(()=>{var e=s.join(__dirname,"..",".cache"),r=s.join(e,"locales.json");if(t.existsSync(r))try{return JSON.parse(t.readFileSync(r,"utf8"))}catch(e){}var a=s.resolve(process.cwd(),"_locales");return t.existsSync(a)?(a=t.readdirSync(a,{withFileTypes:!0}).filter(e=>e.isDirectory()).map(e=>e.name).filter(e=>/^\w{2}[-_]?\w{0,2}$/.test(e)),t.mkdirSync(e,{recursive:!0}),data.atomicWrite(r,JSON.stringify(a,null,2)),a):["en"]})(),n=new Set(r),o="en";return(a=a.filter(e=>!n.has(e))).length&&(o=a[Math.floor(Math.random()*a.length)]),log.debug(`Random language: ${o}
7
+ `),o},async getMsgs(t="en"){if(t=module.exports.formatCode(t),env.msgs&&t==cli.lang)return env.msgs;let e=data.flatten(require(`../../${env.devMode?"../_locales/en/":"data/"}messages.json`));if(!t.startsWith("en")){var s=require("./jsdelivr"+env.modExt).commitURL(cli.commitHashes.locales)+"/_locales/";let r=s+t+"/messages.json",a=0;for(;a<3;)try{e=data.flatten(await(await data.fetch(r)).json());break}catch(e){if(3<=++a)break;log.debug(r=t.includes("-")&&1==a?r.replace(/([^_]*)_[^/]*(\/.*)/,"$1$2"):s+"en/messages.json")}}return e},getSysLang(){try{var e;return"win32"==process.platform?require("child_process").execSync("(Get-Culture).TwoLetterISOLanguageName",{shell:"powershell",encoding:"utf-8"}).trim():((e=process.env).LANG||e.LANGUAGE||e.LC_ALL||e.LC_MESSAGES||e.LC_NAME).split(".")[0]}catch(e){return log.error(cli.msgs.error_failedToFetchSysLang+":",e.message),"en"}},validateLangCode(e){return"string"==typeof e&&/^[a-z]{2,8}(?:[-_][a-z]{2,3})?$/i.test(e)}};
@@ -3,10 +3,10 @@
3
3
  * Source: https://github.com/adamlui/js-utils/tree/main/generate-pw/src
4
4
  * Documentation: https://github.com/adamlui/js-utils/tree/main/generate-pw/docs
5
5
  */
6
- module.exports={colors:{nc:"",br:"",by:"",bo:"",bg:"",bw:"",blk:"",tlBG:""},configURL(){this.info(`
6
+ module.exports={colors:{nc:"",br:"",by:"",bo:"",bg:"",bw:"",gry:"",blk:"",tlBG:""},configURL(){this.info(`
7
7
  ${cli.msgs.info_exampleValidConfigFile}: `+cli.urls.config)},configURLandExit(...s){this.error(...s),this.configURL(),process.exit(1)},data(s){console.log(`
8
8
  `+this.colors.bw+s+this.colors.nc)},debug(s){env.debugMode&&console.debug(`
9
- ${this.colors.bo}DEBUG:`,s,this.colors.nc,"\n")},error(...s){console.error(`
9
+ ${this.colors.bo}DEBUG:`,s,this.colors.nc,"\n")},dim(s){console.log(""+this.colors.gry+s+this.colors.nc)},error(...s){console.error(`
10
10
  ${this.colors.br}ERROR:`,...s,this.colors.nc)},errorAndExit(...s){this.error(...s),this.helpCmdAndDocURL(),process.exit(1)},ifNotQuiet(s){cli.config.quietMode||console.info(s)},info(s){console.info(`
11
11
  `+this.colors.by+s+this.colors.nc)},tip(s){console.info(this.colors.by+"TIP: "+s+this.colors.nc)},success(s){console.log(`
12
12
  `+this.colors.bg+s+this.colors.nc)},warn(...s){console.warn(`
@@ -15,8 +15,8 @@ ${this.colors.bo}WARNING:`,...s,this.colors.nc)},help(s=["header","usage","param
15
15
  ${this.colors.bw}o ${cli.msgs.helpSection_usage}:`+this.colors.nc,` ${this.colors.bw}» `+this.colors.bg+cli.cmdFormat+this.colors.nc],params:[`
16
16
  ${this.colors.bw}o ${cli.msgs.helpSection_params}:`+this.colors.nc,` --length=n ${cli.msgs.optionDesc_length}.`,` --qty=n ${cli.msgs.optionDesc_qty}.`,` --charset=chars ${cli.msgs.optionDesc_charset}.`,` --exclude=chars ${cli.msgs.optionDesc_exclude}.`,` --ui-lang="code" ${cli.msgs.optionDesc_uiLang}.`,` --config="path/to/file" ${cli.msgs.optionDesc_config}.`],flags:[`
17
17
  ${this.colors.bw}o ${cli.msgs.helpSection_flags}:`+this.colors.nc,` -w, --weak ${cli.msgs.optionDesc_weak}.`,` -b, --basic ${cli.msgs.optionDesc_basic}.`,` -t, --strong ${cli.msgs.optionDesc_strong}.`,` -N, --no-numbers ${cli.msgs.optionDesc_excludeNums}.`,` -Y, --no-symbols ${cli.msgs.optionDesc_excludeSymbols}.`,` -L, --no-lowercase ${cli.msgs.optionDesc_noLower}.`,` -U, --no-uppercase ${cli.msgs.optionDesc_noUpper}.`,` -s, --similar-chars ${cli.msgs.optionDesc_similarChars}.`,` -S, --unstrict ${cli.msgs.optionDesc_unstrict}.`,` -e, --entropy ${cli.msgs.optionDesc_entropy}.`,` -q, --quiet ${cli.msgs.optionDesc_quiet}.`],cmds:[`
18
- ${this.colors.bw}o ${cli.msgs.helpSection_cmds}:`+this.colors.nc,` -i, --init ${cli.msgs.optionDesc_init}.`,` -h, --help ${cli.msgs.optionDesc_help}.`,` -v, --version ${cli.msgs.optionDesc_version}.`]};s.forEach(n=>o[n]?.forEach(o=>{{var e=/header|usage/.test(n)?1:29;let i=process.stdout.columns||80,s=o.match(/\S+|\s+/g),c=[],l="";s.forEach(s=>{var o=i-(c.length?e:0);l.length+"| ".length+s.length>o&&(c.push(c.length?l.trimStart():l),l=""),l+=s}),c.push(c.length?l.trimStart():l),c.forEach((s,o)=>console.info("| "+(0==o?s:" ".repeat(e)+s)))}})),console.info(`
19
- ${cli.msgs.info_moreHelp}, ${cli.msgs.info_visit}: `+this.colors.bw+cli.urls.docs+this.colors.nc)},helpCmdAndDocURL(){console.info(`
18
+ ${this.colors.bw}o ${cli.msgs.helpSection_cmds}:`+this.colors.nc,` -i, --init ${cli.msgs.optionDesc_init}.`,` -h, --help ${cli.msgs.optionDesc_help}.`,` -v, --version ${cli.msgs.optionDesc_version}.`]};s.forEach(t=>o[t]?.forEach(o=>{{var e=/header|usage/.test(t)?1:29;let i=process.stdout.columns||80,s=o.match(/\S+|\s+/g),c=[],l="";s.forEach(s=>{var o=i-(c.length?e:0);l.length+"| ".length+s.length>o&&(c.push(c.length?l.trimStart():l),l=""),l+=s}),c.push(c.length?l.trimStart():l),c.forEach((s,o)=>console.info("| "+(0==o?s:" ".repeat(e)+s)))}})),console.info(`
19
+ ${cli.msgs.info_moreHelp}, ${cli.msgs.info_visit}: `+this.colors.bw+cli.urls.cliDocs+this.colors.nc)},helpCmdAndDocURL(){console.info(`
20
20
  ${cli.msgs.info_moreHelp}, ${cli.msgs.info_type} ${cli.name} --help' ${cli.msgs.info_or} ${cli.msgs.info_visit}
21
- `+this.colors.bw+cli.urls.docs+this.colors.nc)},version(){var s=require(`./pkg${env.devMode?"":".min"}.js`).getVer;this.info(cli.name),this.data(`${cli.msgs.prefix_globalVer}: ${s("global")||"none"}
21
+ `+this.colors.bw+cli.urls.docs+this.colors.nc)},version(){var s=require("./pkg"+env.modExt).getVer;this.info(cli.name),this.data(`${cli.msgs.prefix_globalVer}: ${s("global")||"none"}
22
22
  ${cli.msgs.prefix_localVer}: `+(s("local")||"none"))}};
@@ -3,4 +3,4 @@
3
3
  * Source: https://github.com/adamlui/js-utils/tree/main/generate-pw/src
4
4
  * Documentation: https://github.com/adamlui/js-utils/tree/main/generate-pw/docs
5
5
  */
6
- let log=require(`./log${env.devMode?"":".min"}.js`);module.exports={getVer(e="any"){let r;if("global"!=e)try{var l=require("path").resolve(process.cwd(),"node_modules",cli.name,"package.json");r=require(l).version}catch(e){log.debug(cli.msgs.error_readingLocalPkgVer+": "+e.message)}if("global"==e||"all"==e&&!r)try{r=require("child_process").execSync(`npm view ${JSON.stringify(cli.name)} version`).toString().trim()}catch(e){log.debug(cli.msgs.error_failedToFetchGlobalVer+": "+e.message)}return r}};
6
+ let log=require("./log"+env.modExt);module.exports={getVer(e="any"){let r;if("global"!=e)try{var l=require("path").resolve(process.cwd(),"node_modules",cli.name,"package.json");r=require(l).version}catch(e){log.debug(cli.msgs.error_readingLocalPkgVer+": "+e.message)}if("global"==e||"all"==e&&!r)try{r=require("child_process").execSync(`npm view ${JSON.stringify(cli.name)} version`).toString().trim()}catch(e){log.debug(cli.msgs.error_failedToFetchGlobalVer+": "+e.message)}return r}};
@@ -3,5 +3,5 @@
3
3
  * Source: https://github.com/adamlui/js-utils/tree/main/generate-pw/src
4
4
  * Documentation: https://github.com/adamlui/js-utils/tree/main/generate-pw/docs
5
5
  */
6
- let fs=require("fs"),log=require(`./log${env.devMode?"":".min"}.js`),path=require("path");(globalThis.cli??={}).config={},module.exports={configFilename:"generate-pw.config.mjs",controls:{length:{type:"param",defaultVal:12,regex:/^--?length(?:=.*|$)/,parser:e=>parseInt(e,10)},qty:{type:"param",defaultVal:1,regex:/^--?qu?a?n?ti?t?y(?:=.*|$)/,parser:e=>parseInt(e,10)},charset:{type:"param",regex:/^--?charse?t?(?:=.*|$)/},excludeChars:{type:"param",regex:/^--?exclude(?:=.*|$)/},uiLang:{type:"param",regex:/^--?ui-?lang(?:=.*|$)/},config:{type:"param",regex:/^--?config(?:=.*|$)/},weak:{type:"flag",mode:!0,regex:/^--?(?:w|weak)$/},basic:{type:"flag",mode:!0,regex:/^--?(?:b|basic)$/},strong:{type:"flag",mode:!0,regex:/^--?(?:t|strong)$/},excludeNums:{type:"flag",regex:/^--?(?:N|(?:exclude|disable|no)-?num(?:ber)?s?=?(?:true|1)?)$/},excludeSymbols:{type:"flag",regex:/^--?(?:Y|(?:exclude|disable|no)-?symbols?=?(?:true|1)?)$/},excludeLowerChars:{type:"flag",regex:/^--?(?:L|(?:exclude|disable|no)-?lower-?(?:case)?|lower-?(?:case)?=(?:false|0))$/},excludeUpperChars:{type:"flag",regex:/^--?(?:U|(?:exclude|disable|no)-?upper-?(?:case)?|upper-?(?:case)?=(?:false|0))$/},similarChars:{type:"flag",regex:/^--?(?:s|(?:include-?)?similar-?chars?=?(?:true|1)?)$/},unstrict:{type:"flag",regex:/^--?(?:S|(?:un-?strict)?(?:-?mode)?)$/},entropy:{type:"flag",regex:/^--?e(?:ntropy)?$/},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(e=this.configFilename){var i={target:path.resolve(process.cwd(),e)};if(fs.existsSync(i.target))return log.warn(cli.msgs.warn_configFileExists+":",i.target);if(fs.existsSync(i.src=path.resolve(__dirname,"../../"+(env.devMode?"../":"data/")+e)))fs.copyFileSync(i.src,i.target);else{cli.version??=require(`./pkg${env.devMode?"":".min"}.js`).getVer("local");var t=require(`./data${env.devMode?"":".min"}.js`),r=cli.version?cli.name+"-"+cli.version:"latest",r=cli.urls.jsdelivr+`@${r}/${cli.name}/`+e;log.data(cli.msgs.info_fetchingRemoteConfigFrom+` ${r}...`);try{var s=await t.fetch(r);if(!s.ok)return log.warn(`${cli.msgs.warn_remoteConfigNotFound}: ${r} (${s.status})`);t.atomicWrite(i.target,await s.text())}catch(e){return log.warn(cli.msgs.warn_remoteConfigFailed+`: ${r} `+e.message)}}log.success(`${cli.msgs.info_configFileCreated}: ${i.target}\n`),log.tip(cli.msgs.tip_editToSetDefaults+"."),log.tip(cli.msgs.tip_cliArgsPrioritized+".")},load(e=Object.keys(this.controls)){let s=[].concat(e);if(arguments.length||cli.defaultsSet||(s.forEach(e=>{var i=this.controls[e];i.mode||"cmd"==i.type||(cli.config[e]??=i.defaultVal??("flag"!=i.type&&""))}),cli.defaultsSet=!0),!cli.configPathTried){e=env.args.find(e=>this.controls.config.regex.test(e));if(e){/=/.test(e)||log.errorAndExit(`[${e}] `+cli.msgs.error_mustIncludePath);e=e.split("=")[1];cli.configPath=path.isAbsolute(e)?e:path.resolve(process.cwd(),e),fs.existsSync(cli.configPath)||log.configURLandExit(cli.msgs.error_configFileNotFound+":",cli.configPath)}else for(var i of["mjs","cjs","js"]){i=path.resolve(process.cwd(),this.configFilename.replace(/\.[^.]+$/,"."+i));if(fs.existsSync(i)){cli.configPath=i;break}}cli.configPathTried=!0}if(cli.configPath)try{let e=require(cli.configPath),t=e?.default??e;t&&"object"==typeof t||log.configURLandExit(cli.msgs.error_invalidConfigFile+"."),Object.assign(cli.config,arguments.length?s.reduce((e,i)=>t[i]?{...e,[i]:t[i]}:e,{}):t)}catch(e){log.configURLandExit(cli.msgs.error_failedToLoadConfigFile+":",cli.configPath,`
7
- `+e.message)}return env.args.forEach(i=>{if(!/^[^-]|--?(?:config|debug)/.test(i)){var t=Object.keys(this.controls).find(e=>this.controls[e]?.regex?.test(i));if(t||arguments.length||log.errorAndExit(`[${i}] ${cli.msgs.error_notRecognized}.`),s.includes(t)){var r=this.controls[t];if("cmd"!=r.type){let e="param"!=r.type||i.split("=")[1]?.trim();r.mode?cli.config.mode=t.replace(/mode$/i,"").toLowerCase():((r=r.parser)&&(e=r(e),isNaN(e)||e<1)&&log.errorAndExit(`[${t}] ${cli.msgs.error_nonPositiveNum}.`),cli.config[t]=e)}}}}),cli.config}};
6
+ let fs=require("fs"),log=require("./log"+env.modExt),path=require("path");(globalThis.cli??={}).config={},module.exports={configFilename:"generate-pw.config.mjs",controls:{length:{type:"param",valType:"positiveInt",defaultVal:12,regex:/^--?length(?:=.*|$)/},qty:{type:"param",valType:"positiveInt",defaultVal:1,regex:/^--?qu?a?n?ti?t?y(?:=.*|$)/},charset:{type:"param",regex:/^--?charse?t?(?:=.*|$)/},excludeChars:{type:"param",regex:/^--?exclude(?:=.*|$)/},uiLang:{type:"param",valType:"langCode",regex:/^--?ui-?lang(?:=.*|$)/},config:{type:"param",valType:"filepath",regex:/^--?config(?:=.*|$)/},weak:{type:"flag",mode:!0,regex:/^--?(?:w|weak)$/},basic:{type:"flag",mode:!0,regex:/^--?(?:b|basic)$/},strong:{type:"flag",mode:!0,regex:/^--?(?:t|strong)$/},excludeNums:{type:"flag",regex:/^--?(?:N|(?:exclude|disable|no)-?num(?:ber)?s?=?(?:true|1)?)$/},excludeSymbols:{type:"flag",regex:/^--?(?:Y|(?:exclude|disable|no)-?symbols?=?(?:true|1)?)$/},excludeLowerChars:{type:"flag",regex:/^--?(?:L|(?:exclude|disable|no)-?lower-?(?:case)?|lower-?(?:case)?=(?:false|0))$/},excludeUpperChars:{type:"flag",regex:/^--?(?:U|(?:exclude|disable|no)-?upper-?(?:case)?|upper-?(?:case)?=(?:false|0))$/},similarChars:{type:"flag",regex:/^--?(?:s|(?:include-?)?similar-?chars?=?(?:true|1)?)$/},unstrict:{type:"flag",regex:/^--?(?:S|(?:un-?strict)?(?:-?mode)?)$/},entropy:{type:"flag",regex:/^--?e(?:ntropy)?$/},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?$/}},load(e=Object.keys(this.controls)){let r=[].concat(e);if(cli.defaultsSet||arguments.length||(r.forEach(e=>{var i=this.controls[e];i.mode||(cli.config[e]??=i.defaultVal??("param"==i.type&&""))}),cli.defaultsSet=!0),!cli.configPathTried){e=env.args.find(e=>this.controls.config.regex.test(e));if(e){/=/.test(e)||log.errorAndExit(`[${e}] `+cli.msgs.error_mustIncludePath);e=e.split("=")[1];cli.configPath=path.isAbsolute(e)?e:path.resolve(process.cwd(),e),fs.existsSync(cli.configPath)||log.configURLandExit(cli.msgs.error_configFileNotFound+":",cli.configPath)}else for(var i of[".mjs",".cjs",".js"]){i=path.resolve(process.cwd(),this.configFilename.replace(/\.[^.]+$/,i));if(fs.existsSync(i)){cli.configPath=i;break}}cli.configPathTried=!0}if(cli.configPath)try{let e=require(cli.configPath),t=e?.default??e;t&&"object"==typeof t||log.configURLandExit(cli.msgs.error_invalidConfigFile+"."),Object.assign(cli.config,arguments.length?r.reduce((e,i)=>t[i]?{...e,[i]:t[i]}:e,{}):t)}catch(e){log.configURLandExit(cli.msgs.error_failedToLoadConfigFile+":",cli.configPath,`
7
+ `+e.message)}return env.args.forEach(i=>{var e,t;/^[^-]|--?(?:config|debug)/.test(i)&&"init"!=i||(!(e=Object.keys(this.controls).find(e=>this.controls[e]?.regex?.test(i)))&&cli.msgs&&log.errorAndExit(`[${i}] ${cli.msgs.error_notRecognized}.`),r.includes(e)&&((t=this.controls[e]).mode?cli.config.mode=e.replace(/mode$/i,"").toLowerCase():cli.config[e]="param"!=t.type||(i.split("=")[1]?.trim()??"")))}),this.parseValidateConfig(r),1==r.length?cli.config[r[0]]:cli.config},parseValidateConfig(e=Object.keys(this.controls)){let r=require("./language"+env.modExt);for(let t of[].concat(e)){let e=this.controls[t],i=cli.config[t];e.parser&&!e.parsed&&(cli.config[t]=e.parser(i),e.parsed=!0),e.valType&&{positiveInt(){var e=parseInt(i,10);(isNaN(e)||e<1)&&log.errorAndExit(`[${t}] ${cli.msgs.error_nonPositiveNum}: `+i),cli.config[t]=e},filepath(){i&&!fs.existsSync(i)&&log.errorAndExit(`[${t}] ${cli.msgs.error_invalidFilepath}: `+i)},langCode(){i&&!r.validateLangCode(i)&&log.errorAndExit(`[${t}] ${cli.msgs.error_invalidLangCode}: `+i)}}[e.valType]()}}};
@@ -7,6 +7,8 @@
7
7
  "error_readingLocalPkgVer": { "message": "Error reading local package version" },
8
8
  "error_notRecognized": { "message": "not recognized" },
9
9
  "error_nonPositiveNum": { "message": "argument can only be > 0" },
10
+ "error_invalidFilepath": { "message": "must be a valid existing file path. Got" },
11
+ "error_invalidLangCode": { "message": "is an invalid language code" },
10
12
  "error_invalidURL": { "message": "Invalid URL" },
11
13
  "error_invalidConfigFile": { "message": "Config file must export an object" },
12
14
  "error_configFileNotFound": { "message": "Config file not found" },
@@ -13,6 +13,6 @@
13
13
  "src": "https://github.com/adamlui/js-utils/tree/main/generate-pw/src"
14
14
  },
15
15
  "commitHashes": {
16
- "locales": "c20c989"
16
+ "locales": "69618f8"
17
17
  }
18
18
  }
@@ -3,4 +3,4 @@
3
3
  * Source: https://github.com/adamlui/js-utils/tree/main/generate-pw/src
4
4
  * Documentation: https://github.com/adamlui/js-utils/tree/main/generate-pw/docs
5
5
  */
6
- function generatePassword(s={}){var e={verbose:!0,length:12,qty:1,strength:"",charset:"",exclude:"",numbers:!0,symbols:!0,lowercase:!0,uppercase:!0,similarChars:!1,strict:!0,entropy:!1};if(log.prefix="generatePassword()",validateOptions({options:s,defaultOptions:e,helpURL:"https://github.com/adamlui/js-utils/tree/main/generate-pw/docs/#generatepasswordoptions",exampleCall:"generatePassword({ verbose: false, numbers: true })"})){if(1<(s=(s={...e,...s}).strength&&(e=api.strengthPresets[s.strength.toLowerCase()])?{...s,...e}:s).qty){let{qty:e,...r}=s;return generatePasswords(e,r)}{var a,e="generatePasswords"==generatePassword.caller?.name;s.verbose&&!e&&log.info("Initializing character set...");let r=s.charset?.toString()||(s.numbers?api.charsets.numbers:"")+(s.symbols?api.charsets.symbols:"")+(s.lowercase?api.charsets.lower:"")+(s.uppercase?api.charsets.upper:""),t=(""==r&&(r=api.charsets.lower+api.charsets.upper),s.exclude&&(s.verbose&&!e&&log.info("Removing excluded characters..."),r=r.replace(new RegExp(`[${s.exclude}]`,"g"),"")),s.similarChars||(s.verbose&&!e&&log.info("Excluding similar characters..."),r=r.replace(/[o0Oil1|]/g,"")),s.verbose&&!e&&log.info("Generating password..."),"");for(let e=0;e<s.length;e++){var o=randomInt(0,r.length);t+=r[o]}return s.strict&&(s.verbose&&!e&&log.info("Enforcing strict mode..."),a=["numbers","symbols","lower","upper"].filter(e=>s[e]||s[e+"case"]),t=strictify(t,a)),s.verbose&&(e||(log.info("Password generated!"),"undefined"!=typeof window&&log.info("Check returned string.")),s.entropy)&&(e=(a=r.length)<2?0:Math.log2(a**t.length),log.info(`Estimated entropy: ${e.toFixed(2)} bits (charset length: ${a})`)),t}}}function generatePasswords(r,t={}){var e="https://github.com/adamlui/js-utils/tree/main/generate-pw/docs/#generatepasswordsqty-options",s={verbose:!0,length:12,strength:"",charset:"",exclude:"",numbers:!0,symbols:!0,lowercase:!0,uppercase:!0,similarChars:!1,strict:!0,entropy:!1};if(log.prefix="generatePasswords()",r=parseInt(r,10),isNaN(r)||r<1)return log.error("1st arg <qty> can only be an integer > 0."),log.helpURL(e);if(validateOptions({options:t,defaultOptions:s,helpURL:e,exampleCall:"generatePasswords(3, { verbose: false, symbols: true })"})){(t=(t={...s,...t}).strength&&(e=api.strengthPresets[t.strength.toLowerCase()])?{...t,...e}:t).verbose&&log.info(`Generating password${1<r?"s":""}...`);var a=[];for(let e=0;e<r;e++)a.push(generatePassword(t));return t.verbose&&(log.info(`Password${1<r?"s":""} generated!`),"undefined"!=typeof window)&&log.info("Check returned array."),a}}function strictify(o,n=["numbers","symbols","lower","upper"],e={}){var r="https://github.com/adamlui/js-utils/tree/main/generate-pw/docs/#strictifypassword-requiredchartypes-options",i={verbose:!0};if(log.prefix="strictify()","string"!=typeof o)return log.error("1st arg <password> must be a string."),log.helpURL(r);var t,s=["numbers","symbols","lower","upper"];for(t of n=[].concat(n))if(!s.includes(t))return log.error(`2nd arg \`${t}\` is an invalid character type.`),void log.info([`Valid character types: ['${s.join("', '")}']`,"Pass one as a string or more as an array, or all types will be required.","For more help, please visit "+r].join("\n"));if(validateOptions({options:e,defaultOptions:i,helpURL:r,exampleCall:"strictify('pa55word', ['symbol', 'upper'], { verbose: false })"})){e={...i,...e};let r={},t=[];n.forEach(e=>r[e]=!1);for(let e=0;e<o.length;e++)for(var l of n)!r[l]&&api.charsets[l].includes(o[e])&&(r[l]=!0,t.push(e));e.verbose&&log.info("Strictifying password...");var p,g=Math.min(o.length,n.length);let s=0,a=o;for(p of n)if(s<g&&!r[p]){let e;for(;e=randomInt(0,o.length),t.includes(e););t.push(e);var c=api.charsets[p]||api.charsets[p+"s"];a=a.substring(0,e)+c[randomInt(0,c.length)]+a.substring(e+1),s++}return e.verbose&&(0<s?(log.info("Password is now strict!"),log.info("Check returned string.")):(log.info(`Password already includes ${n.join(" + ")} characters!`),log.info("No modifications made."))),a}}function validateStrength(r,t={}){var e="https://github.com/adamlui/js-utils/tree/main/generate-pw/docs/#validatestrengthpassword-options",s={minlength:12,minLower:1,minUpper:1,minNumber:1,minSymbol:1},a={verbose:!0};if(log.prefix="validateStrength()","string"!=typeof r)return log.error("1st arg <password> must be a string."),log.helpURL(e);if(validateOptions({options:t,defaultOptions:a,helpURL:e,exampleCall:"validateStrength('pa55word', { verbose: false })"})){(t={...a,...t}).verbose&&log.info("Validating password strength...");var o,n={lower:0,upper:0,number:0,symbol:0};for(o of r)for(var i of Object.keys(n))(api.charsets[i]||api.charsets[i+"s"]).includes(o)&&n[i]++;var l,p,g=[];r.length<s.minLength&&g.push(`Make it at least ${s.minLength} characters long.`);for(l of Object.keys(n))n[l]<s["min"+l[0].toUpperCase()+l.slice(1)]&&g.push(`Include at least one ${l}${["upper","lower"].includes(l)?"case letter":""}.`);let e=0;e+=r.length>=s.minLength?20:0;for(p of Object.keys(n))e+=n[p]>=s["min"+p[0].toUpperCase()+p.slice(1)]?20:0;return t.verbose&&(log.info("Password strength validated!"),log.info("Check returned object for score/recommendations.")),{strengthScore:e,recommendations:g,isGood:80<=e}}}function randomInt(e,r){var t;return"undefined"==typeof require?(t=(window.crypto||window.msCrypto)?.getRandomValues(new Uint32Array(1))[0]/4294967295||Math.random(),Math.floor(t*(r-e))+e):require("crypto").randomInt(e,r)}function validateOptions({options:e,defaultOptions:r,helpURL:t,exampleCall:s}){var a=Object.keys(r).filter(e=>"boolean"==typeof r[e]),o=Object.keys(r).filter(e=>Number.isInteger(r[e]));if("object"!=typeof e)return i=s.split(",").findIndex(e=>e.trim().startsWith("{"))+1,i+=["st","nd","rd"][i-1]||"th",log.error(`${"0th"==i?"[O":i+" arg [o"}ptions] can only be an object of key/vals.`),log.info("Example valid call:",s),log.validOptions(r),log.helpURL(t),!1;var n,i=["weak","basic","strong"];if("strength"in e&&e.strength&&!i.includes(e.strength.toLowerCase()))return log.error("[strength] must be one of: "+i.join(", ")),log.helpURL(t),!1;for(n in e){if(!Object.prototype.hasOwnProperty.call(r,n))return log.error(`\`${n}\` is an invalid option.`),log.validOptions(r),log.helpURL(t),!1;if(a.includes(n)&&"boolean"!=typeof e[n])return log.error(`[${n}] option can only be \`true\` or \`false\`.`),log.helpURL(t),!1;if(o.includes(n)&&(e[n]=parseInt(e[n],10),isNaN(e[n])||e[n]<1))return log.error(`[${n}] option can only be an integer > 0.`),log.helpURL(t),!1}return!0}Object.assign(globalThis.api??={},{name:"generate-pw",aliases:{generatePassword:["generate","generatepassword","generatepw","generatePw","generatePW","Generate","Generatepassword","GeneratePassword","Generatepw","GeneratePw","GeneratePW"],generatePasswords:["generatepasswords","generatepws","generatePws","generatePWs","generatePWS","Generatepasswords","GeneratePasswords","Generatepws","GeneratePws","GeneratePWs","GeneratePWS"],strictify:["Strictify"],validateStrength:["validate","Validate","validatestrength","Validatestrength","ValidateStrength"]},charsets:{lower:"abcdefghijklmnopqrstuvwxyz",upper:"ABCDEFGHIJKLMNOPQRSTUVWXYZ",numbers:"0123456789",symbols:"!@#$%^&*()-_=+[]{}/\\|;:'\",.<>?"},strengthPresets:{weak:{length:6,lowercase:!0,uppercase:!1,numbers:!1,symbols:!1,similarChars:!0,strict:!1},basic:{length:8,lowercase:!0,uppercase:!0,numbers:!0,symbols:!1,similarChars:!0,strict:!1},strong:{length:12,lowercase:!0,uppercase:!0,numbers:!0,symbols:!0,similarChars:!1,strict:!0}}});let log={prefix:api.name,error(...e){console.error(this.prefix+" » ERROR:",...e)},helpURL(e=api.urls?.docs){this.info("For more help, please visit",e)},info(...e){console.info(this.prefix+" »",...e)},validOptions(e){var r=Object.keys(e).join(", "),e=JSON.stringify(e,null,2).replace(/"([^"]+)":/g,"$1:").replace(/"/g,"'").replace(/\n\s*/g," ");this.info(`Valid options: [${r}]`),this.info("If omitted, default settings are: "+e)}};api.exports={generatePassword:generatePassword,generatePasswords:generatePasswords,strictify:strictify,validateStrength:validateStrength};try{module.exports={...api.exports}}catch(e){}try{window.pw={...api.exports}}catch(e){}for(let r in api.aliases){try{api.aliases[r].forEach(e=>module.exports[e]??=module.exports[r])}catch(e){}try{api.aliases[r].forEach(e=>window.pw[e]??=window.pw[r])}catch(e){}}
6
+ function generatePassword(s={}){var e={verbose:!0,length:12,qty:1,strength:"",charset:"",exclude:"",numbers:!0,symbols:!0,lowercase:!0,uppercase:!0,similarChars:!1,strict:!0,entropy:!1};if(log.prefix="generatePassword()",validateOptions({options:s,defaultOptions:e,helpURL:"https://github.com/adamlui/js-utils/tree/main/generate-pw/docs/#generatepasswordoptions",exampleCall:"generatePassword({ verbose: false, numbers: true })"})){if(1<(s=(s={...e,...s}).strength&&(e=api.strengthPresets[s.strength.toLowerCase()])?{...s,...e}:s).qty){let{qty:e,...r}=s;return generatePasswords(e,r)}{var a,e="generatePasswords"==generatePassword.caller?.name;s.verbose&&!e&&log.info("Initializing character set...");let r=s.charset?.toString()||(s.numbers?api.charsets.numbers:"")+(s.symbols?api.charsets.symbols:"")+(s.lowercase?api.charsets.lower:"")+(s.uppercase?api.charsets.upper:""),t=(""==r&&(r=api.charsets.lower+api.charsets.upper),s.exclude&&(s.verbose&&!e&&log.info("Removing excluded characters..."),r=r.replace(new RegExp(`[${s.exclude}]`,"g"),"")),s.similarChars||(s.verbose&&!e&&log.info("Excluding similar characters..."),r=r.replace(/[o0Oil1|]/g,"")),s.verbose&&!e&&log.info("Generating password..."),"");for(let e=0;e<s.length;e++){var o=randomInt(0,r.length);t+=r[o]}return s.strict&&!s.charset&&(s.verbose&&!e&&log.info("Enforcing strict mode..."),a=["numbers","symbols","lower","upper"].filter(e=>s[e]||s[e+"case"]),t=strictify(t,a)),s.verbose&&(e||(log.info("Password generated!"),"undefined"!=typeof window&&log.info("Check returned string.")),s.entropy)&&(e=(a=r.length)<2?0:Math.log2(a**t.length),log.info(`Estimated entropy: ${e.toFixed(2)} bits (charset length: ${a})`)),t}}}function generatePasswords(r,t={}){var e="https://github.com/adamlui/js-utils/tree/main/generate-pw/docs/#generatepasswordsqty-options",s={verbose:!0,length:12,strength:"",charset:"",exclude:"",numbers:!0,symbols:!0,lowercase:!0,uppercase:!0,similarChars:!1,strict:!0,entropy:!1};if(log.prefix="generatePasswords()",r=parseInt(r,10),(isNaN(r)||r<1)&&log.errHelpURLandThrow({errMsg:"1st arg <qty> can only be an integer > 0.",helpURL:e}),validateOptions({options:t,defaultOptions:s,helpURL:e,exampleCall:"generatePasswords(3, { verbose: false, symbols: true })"})){(t=(t={...s,...t}).strength&&(e=api.strengthPresets[t.strength.toLowerCase()])?{...t,...e}:t).verbose&&log.info(`Generating password${1<r?"s":""}...`);var a=[];for(let e=0;e<r;e++)a.push(generatePassword(t));return t.verbose&&(log.info(`Password${1<r?"s":""} generated!`),"undefined"!=typeof window)&&log.info("Check returned array."),a}}function strictify(o,n=["numbers","symbols","lower","upper"],e={}){var r,t="https://github.com/adamlui/js-utils/tree/main/generate-pw/docs/#strictifypassword-requiredchartypes-options",i={verbose:!0},s=(log.prefix="strictify()","string"!=typeof o&&log.errHelpURLandThrow({errMsg:"1st arg <password> must be a string.",helpURL:t}),["numbers","symbols","lower","upper"]);for(r of n=[].concat(n))if(!s.includes(r))return log.error(`2nd arg \`${r}\` is an invalid character type.`),void log.info([`Valid character types: ['${s.join("', '")}']`,"Pass one as a string or more as an array, or all types will be required.","For more help, please visit "+t].join("\n"));if(o.length<n.length){for(;n.length>o.length;)n.splice(randomInt(0,n.length),1);log.info("Reduced required char types to: "+n.join(", "))}if(validateOptions({options:e,defaultOptions:i,helpURL:t,exampleCall:"strictify('pa55word', ['symbol', 'upper'], { verbose: false })"})){e={...i,...e};let r={},t=[];n.forEach(e=>r[e]=!1);for(let e=0;e<o.length;e++)for(var l of n)!r[l]&&api.charsets[l].includes(o[e])&&(r[l]=!0,t.push(e));e.verbose&&log.info("Strictifying password...");var p,g=Math.min(o.length,n.length);let s=0,a=o;for(p of n)if(s<g&&!r[p]){let e;for(;e=randomInt(0,o.length),t.includes(e););t.push(e);var d=api.charsets[p]||api.charsets[p+"s"];a=a.substring(0,e)+d[randomInt(0,d.length)]+a.substring(e+1),s++}return e.verbose&&(0<s?(log.info("Password is now strict!"),log.info("Check returned string.")):(log.info(`Password already includes ${n.join(" + ")} characters!`),log.info("No modifications made."))),a}}function validateStrength(r,t={}){var e="https://github.com/adamlui/js-utils/tree/main/generate-pw/docs/#validatestrengthpassword-options",s={minlength:12,minLower:1,minUpper:1,minNumber:1,minSymbol:1},a={verbose:!0};if(log.prefix="validateStrength()","string"!=typeof r&&log.errHelpURLandThrow({errMsg:"1st arg <password> must be a string.",helpURL:e}),validateOptions({options:t,defaultOptions:a,helpURL:e,exampleCall:"validateStrength('pa55word', { verbose: false })"})){(t={...a,...t}).verbose&&log.info("Validating password strength...");var o,n={lower:0,upper:0,number:0,symbol:0};for(o of r)for(var i of Object.keys(n))(api.charsets[i]||api.charsets[i+"s"]).includes(o)&&n[i]++;var l,p,g=[];r.length<s.minLength&&g.push(`Make it at least ${s.minLength} characters long.`);for(l of Object.keys(n))n[l]<s["min"+l[0].toUpperCase()+l.slice(1)]&&g.push(`Include at least one ${l}${["upper","lower"].includes(l)?"case letter":""}.`);let e=0;e+=r.length>=s.minLength?20:0;for(p of Object.keys(n))e+=n[p]>=s["min"+p[0].toUpperCase()+p.slice(1)]?20:0;return t.verbose&&(log.info("Password strength validated!"),log.info("Check returned object for score/recommendations.")),{strengthScore:e,recommendations:g,isGood:80<=e}}}function randomInt(e,r){var t;return"undefined"==typeof require?(t=(window.crypto||window.msCrypto)?.getRandomValues(new Uint32Array(1))[0]/4294967295||Math.random(),Math.floor(t*(r-e))+e):require("crypto").randomInt(e,r)}function validateOptions({options:e,defaultOptions:r,helpURL:t,exampleCall:s}){var a=Object.keys(r).filter(e=>"boolean"==typeof r[e]),o=Object.keys(r).filter(e=>Number.isInteger(r[e]));if("object"!=typeof e)return i=s.split(",").findIndex(e=>e.trim().startsWith("{"))+1,i+=["st","nd","rd"][i-1]||"th",log.error(`${"0th"==i?"[O":i+" arg [o"}ptions] can only be an object of key/vals.`),log.info("Example valid call:",s),log.validOptions(r),log.helpURL(t),!1;var n,i=["weak","basic","strong"];if("strength"in e&&e.strength&&!i.includes(e.strength.toLowerCase()))return log.error("[strength] must be one of: "+i.join(", ")),log.helpURL(t),!1;for(n in e){if(!Object.prototype.hasOwnProperty.call(r,n))return log.error(`\`${n}\` is an invalid option.`),log.validOptions(r),log.helpURL(t),!1;if(a.includes(n)&&"boolean"!=typeof e[n])return log.error(`[${n}] option can only be \`true\` or \`false\`.`),log.helpURL(t),!1;if(o.includes(n)&&(e[n]=parseInt(e[n],10),isNaN(e[n])||e[n]<1))return log.error(`[${n}] option can only be an integer > 0.`),log.helpURL(t),!1}return!0}Object.assign(globalThis.api??={},{name:"generate-pw",aliases:{generatePassword:["generate","generatepassword","generatepw","generatePw","generatePW","Generate","Generatepassword","GeneratePassword","Generatepw","GeneratePw","GeneratePW"],generatePasswords:["generatepasswords","generatepws","generatePws","generatePWs","generatePWS","Generatepasswords","GeneratePasswords","Generatepws","GeneratePws","GeneratePWs","GeneratePWS"],strictify:["Strictify"],validateStrength:["validate","Validate","validatestrength","Validatestrength","ValidateStrength"]},charsets:{lower:"abcdefghijklmnopqrstuvwxyz",upper:"ABCDEFGHIJKLMNOPQRSTUVWXYZ",numbers:"0123456789",symbols:"!@#$%^&*()-_=+[]{}/\\|;:'\",.<>?"},strengthPresets:{weak:{length:6,lowercase:!0,uppercase:!1,numbers:!1,symbols:!1,similarChars:!0,strict:!1},basic:{length:8,lowercase:!0,uppercase:!0,numbers:!0,symbols:!1,similarChars:!0,strict:!1},strong:{length:12,lowercase:!0,uppercase:!0,numbers:!0,symbols:!0,similarChars:!1,strict:!0}}});let log={prefix:api.name,errHelpURLandThrow({errMsg:e,helpURL:r}){throw this.error(e),this.helpURL(r),new Error(e)},error(...e){console.error(this.prefix+" » ERROR:",...e)},helpURL(e=api.urls?.docs){this.info("For more help, please visit",e)},info(...e){console.info(this.prefix+" »",...e)},validOptions(e){var r=Object.keys(e).join(", "),e=JSON.stringify(e,null,2).replace(/"([^"]+)":/g,"$1:").replace(/"/g,"'").replace(/\n\s*/g," ");this.info(`Valid options: [${r}]`),this.info("If omitted, default settings are: "+e)}};api.exports={generatePassword:generatePassword,generatePasswords:generatePasswords,strictify:strictify,validateStrength:validateStrength};try{module.exports={...api.exports}}catch(e){}try{window.pw={...api.exports}}catch(e){}for(let r in api.aliases){try{api.aliases[r].forEach(e=>module.exports[e]??=module.exports[r])}catch(e){}try{api.aliases[r].forEach(e=>window.pw[e]??=window.pw[r])}catch(e){}}
package/docs/README.md CHANGED
@@ -25,12 +25,12 @@
25
25
  <img height=31 src="https://img.shields.io/npm/dm/generate-pw?logo=npm&color=af68ff&logoColor=white&labelColor=464646&style=for-the-badge"></a>
26
26
  <a href="#%EF%B8%8F-mit-license">
27
27
  <img height=31 src="https://img.shields.io/badge/License-MIT-orange.svg?logo=internetarchive&logoColor=white&labelColor=464646&style=for-the-badge"></a>
28
- <a href="https://github.com/adamlui/js-utils/releases/tag/generate-pw-2.1.0">
29
- <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>
28
+ <a href="https://github.com/adamlui/js-utils/releases/tag/generate-pw-2.1.2">
29
+ <img height=31 src="https://img.shields.io/badge/Latest_Build-2.1.2-44cc11.svg?logo=icinga&logoColor=white&labelColor=464646&style=for-the-badge"></a>
30
30
  <a href="https://www.npmjs.com/package/generate-pw?activeTab=code">
31
31
  <img height=31 src="https://img.shields.io/npm/unpacked-size/generate-pw?style=for-the-badge&logo=ebox&logoColor=white&labelColor=464646&color=blue"></a>
32
- <a href="https://github.com/adamlui/js-utils/blob/generate-pw-2.1.0/generate-pw/dist/generate-pw.min.js">
33
- <img height=31 src="https://img.shields.io/github/size/adamlui/js-utils/generate-pw/dist/generate-pw.min.js?branch=generate-pw-2.1.0&label=Minified%20Size&logo=databricks&logoColor=white&labelColor=464646&color=ff69b4&style=for-the-badge"></a>
32
+ <a href="https://github.com/adamlui/js-utils/blob/generate-pw-2.1.2/generate-pw/dist/generate-pw.min.js">
33
+ <img height=31 src="https://img.shields.io/github/size/adamlui/js-utils/generate-pw/dist/generate-pw.min.js?branch=generate-pw-2.1.2&label=Minified%20Size&logo=databricks&logoColor=white&labelColor=464646&color=ff69b4&style=for-the-badge"></a>
34
34
  <a href="https://sonarcloud.io/component_measures?metric=new_vulnerabilities&id=adamlui_js-utils:generate-pw/src/generate-pw.js">
35
35
  <img height=31 src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fsonarcloud.io%2Fapi%2Fmeasures%2Fcomponent%3Fcomponent%3Dadamlui_js-utils%3Agenerate-pw%2Fsrc%2Fgenerate-pw.js%26metricKeys%3Dvulnerabilities&query=%24.component.measures.0.value&style=for-the-badge&logo=sonarcloud&logoColor=white&labelColor=464646&label=Vulnerabilities&color=gold"></a>
36
36
  <a href="https://github.com/toolleeo/cli-apps#password-managers">
@@ -94,14 +94,14 @@ const pw = require('generate-pw')
94
94
  #### <> HTML script tag:
95
95
 
96
96
  ```html
97
- <script src="https://cdn.jsdelivr.net/npm/generate-pw@2.1.0/dist/generate-pw.min.js"></script>
97
+ <script src="https://cdn.jsdelivr.net/npm/generate-pw@2.1.2/dist/generate-pw.min.js"></script>
98
98
  ```
99
99
 
100
100
  #### ES6:
101
101
 
102
102
  ```js
103
103
  (async () => {
104
- await import('https://cdn.jsdelivr.net/npm/generate-pw@2.1.0/dist/generate-pw.min.js')
104
+ await import('https://cdn.jsdelivr.net/npm/generate-pw@2.1.2/dist/generate-pw.min.js')
105
105
  // Your code here...
106
106
  })()
107
107
  ```
@@ -110,7 +110,7 @@ const pw = require('generate-pw')
110
110
 
111
111
  ```js
112
112
  ...
113
- // @require https://cdn.jsdelivr.net/npm/generate-pw@2.1.0/dist/generate-pw.min.js
113
+ // @require https://cdn.jsdelivr.net/npm/generate-pw@2.1.2/dist/generate-pw.min.js
114
114
  // ==/UserScript==
115
115
 
116
116
  // Your code here...
@@ -118,7 +118,7 @@ const pw = require('generate-pw')
118
118
 
119
119
  <br>
120
120
 
121
- **💡 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/generate-pw/dist/generate-pw.min.js`
121
+ **💡 Note:** To always import the latest version (not recommended in production!) remove the `@2.1.2` version tag from the jsDelivr URL: `https://cdn.jsdelivr.net/npm/generate-pw/dist/generate-pw.min.js`
122
122
 
123
123
  <br>
124
124
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "generate-pw",
3
- "version": "2.1.0",
3
+ "version": "2.1.2",
4
4
  "description": "Randomly generate, strengthen, and validate cryptographically-secure passwords.",
5
5
  "author": {
6
6
  "name": "Adam Lui",
@@ -47,7 +47,7 @@
47
47
  "build:data": "node utils/build --data",
48
48
  "build:json": "node utils/build --json",
49
49
  "debug": "node src/cli --debug",
50
- "translate": "py utils/translate-en-messages.py",
50
+ "translate": "translate-messages",
51
51
  "bump:patch": "bash utils/bump.sh patch",
52
52
  "bump:minor": "bash utils/bump.sh minor",
53
53
  "bump:major": "bash utils/bump.sh major"
@@ -57,12 +57,16 @@
57
57
  "url": "git+https://github.com/adamlui/js-utils.git"
58
58
  },
59
59
  "keywords": [
60
- "password",
60
+ "api",
61
+ "cli",
62
+ "generate",
61
63
  "generator",
64
+ "password",
65
+ "random",
66
+ "rng",
67
+ "security",
62
68
  "unique",
63
- "generate",
64
- "api",
65
- "cli"
69
+ "utility"
66
70
  ],
67
71
  "bugs": {
68
72
  "url": "https://github.com/adamlui/js-utils/issues"
@@ -71,6 +75,6 @@
71
75
  "node-clipboardy": "^1.0.3"
72
76
  },
73
77
  "devDependencies": {
74
- "@adamlui/minify.js": "^2.2.1"
78
+ "@adamlui/minify.js": "^2.3.0"
75
79
  }
76
80
  }