generate-pw 1.5.16 → 2.0.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 +55 -19
- package/dist/cli/index.min.js +5 -18
- 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 +22 -0
- package/dist/cli/lib/settings.min.js +8 -0
- package/dist/data/app.json +2 -1
- package/dist/data/generate-pw.config.mjs +31 -0
- package/dist/data/messages.json +26 -7
- package/dist/generate-pw.min.js +4 -4
- package/docs/README.md +55 -21
- package/package.json +10 -5
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-
|
|
29
|
-
<img height=31 src="https://img.shields.io/badge/Latest_Build-
|
|
28
|
+
<a href="https://github.com/adamlui/js-utils/releases/tag/generate-pw-2.0.0">
|
|
29
|
+
<img height=31 src="https://img.shields.io/badge/Latest_Build-2.0.0-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-
|
|
33
|
-
<img height=31 src="https://img.shields.io/github/size/adamlui/js-utils/generate-pw/dist/generate-pw.min.js?branch=generate-pw-
|
|
32
|
+
<a href="https://github.com/adamlui/js-utils/blob/generate-pw-2.0.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.0.0&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">
|
|
@@ -78,7 +78,7 @@ $ npm install generate-pw
|
|
|
78
78
|
#### ECMAScript*:
|
|
79
79
|
|
|
80
80
|
```js
|
|
81
|
-
import pw from 'generate-pw'
|
|
81
|
+
import pw from 'generate-pw'
|
|
82
82
|
```
|
|
83
83
|
|
|
84
84
|
#### CommonJS:
|
|
@@ -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@
|
|
97
|
+
<script src="https://cdn.jsdelivr.net/npm/generate-pw@2.0.0/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@
|
|
104
|
+
await import('https://cdn.jsdelivr.net/npm/generate-pw@2.0.0/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@
|
|
113
|
+
// @require https://cdn.jsdelivr.net/npm/generate-pw@2.0.0/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 `@
|
|
121
|
+
**💡 Note:** To always import the latest version (not recommended in production!) remove the `@2.0.0` 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
|
|
|
@@ -190,7 +190,7 @@ console.log(strictPW) // sample output: 'a!c2ef'
|
|
|
190
190
|
|
|
191
191
|
**💡 Note:** If no `requiredCharTypes` array is passed, all available types will be required.
|
|
192
192
|
|
|
193
|
-
Available `requiredCharTypes` are: `['
|
|
193
|
+
Available `requiredCharTypes` are: `['numbers', 'symbols', 'lower', 'upper']`
|
|
194
194
|
|
|
195
195
|
Available options (passed as object properties):
|
|
196
196
|
|
|
@@ -245,15 +245,17 @@ Name | Type | Description
|
|
|
245
245
|
----------------------|---------|--------------------------------------------------------------------------------|---------------
|
|
246
246
|
`verbose` | Boolean | Show logging in console/terminal. | `true`
|
|
247
247
|
`length` | Integer | Length of password(s). | `8`
|
|
248
|
-
`qty
|
|
248
|
+
`qty` | Integer | Number of passwords to generate. | `1`
|
|
249
|
+
`strength` | String | `<'weak'\|'basic'\|'strong'>` Apply strength preset. | `''`
|
|
249
250
|
`charset` | String | Characters to include in password(s). | `''`
|
|
250
251
|
`exclude` | String | Characters to exclude from password(s). | `''`
|
|
251
252
|
`numbers` | Boolean | Allow numbers in password(s). | `false`
|
|
252
253
|
`symbols` | Boolean | Allow symbols in password(s). | `false`
|
|
253
254
|
`lowercase` | Boolean | Allow lowercase letters in password(s). | `true`
|
|
254
255
|
`uppercase` | Boolean | Allow uppercase letters in password(s). | `true`
|
|
255
|
-
`
|
|
256
|
-
`strict` | Boolean | Require at least one character from each allowed character set in password(s). | `
|
|
256
|
+
`similarChars` | Boolean | Include similar characters (e.g. o,0,O,i,l,1,\|) in password(s). | `false`
|
|
257
|
+
`strict` | Boolean | Require at least one character from each allowed character set in password(s). | `true`
|
|
258
|
+
`entropy` | Boolean | Calculate/log estimated entropy. | `false`
|
|
257
259
|
|
|
258
260
|
##### _*Only available in [`generatePassword([options])`](#generatepasswordoptions) since [`generatePasswords(qty[, options])`](#generatepasswordsqty-options) takes a `qty` argument_
|
|
259
261
|
|
|
@@ -281,22 +283,56 @@ Parameter options:
|
|
|
281
283
|
--qty=n Generate n password(s).
|
|
282
284
|
--charset=chars Only include chars in password(s).
|
|
283
285
|
--exclude=chars Exclude chars from password(s).
|
|
286
|
+
--config="path/to/file" Load custom config file.
|
|
284
287
|
|
|
285
288
|
Boolean options:
|
|
286
|
-
-
|
|
287
|
-
-
|
|
289
|
+
-w, --weak Generate weak password(s).
|
|
290
|
+
-b, --basic Generate basic strength password(s).
|
|
291
|
+
-t, --strong Generate strong password(s).
|
|
292
|
+
-N, --no-numbers Disallow numbers in password(s).
|
|
293
|
+
-Y, --no-symbols Disallow symbols in password(s).
|
|
288
294
|
-L, --no-lowercase Disallow lowercase letters in password(s).
|
|
289
295
|
-U, --no-uppercase Disallow uppercase letters in password(s).
|
|
290
|
-
-S, --
|
|
291
|
-
-
|
|
292
|
-
allowed character set in password(s).
|
|
296
|
+
-S, --similar-chars Include similar characters in password(s).
|
|
297
|
+
-S, --unstrict Don't require at least one character from
|
|
298
|
+
each allowed character set in password(s).
|
|
299
|
+
-e, --entropy Calculate/log estimated entropy.
|
|
293
300
|
-q, --quiet Suppress all logging except errors.
|
|
294
301
|
|
|
295
|
-
|
|
302
|
+
Commands:
|
|
303
|
+
-i, --init Create config file (in project root).
|
|
296
304
|
-h, --help Display help screen.
|
|
297
305
|
-v, --version Show version number.
|
|
298
306
|
```
|
|
299
307
|
|
|
308
|
+
#
|
|
309
|
+
|
|
310
|
+
### Configuration file
|
|
311
|
+
|
|
312
|
+
**generate-pw** can be customized using a `generate-pw.config.mjs` or `generate-pw.config.js` placed in your project root.
|
|
313
|
+
|
|
314
|
+
Example defaults:
|
|
315
|
+
|
|
316
|
+
```js
|
|
317
|
+
export default {
|
|
318
|
+
length: 12, // length of passwords to generate
|
|
319
|
+
qty: 1, // # of passwords to generate
|
|
320
|
+
strength: '', // <'weak'|'basic'|'strong'> apply strength preset
|
|
321
|
+
charset: '', // only include chars in password(s)
|
|
322
|
+
exclude: '', // exclude chars from password(s)
|
|
323
|
+
excludeNums: false, // disallow numbers in password(s)
|
|
324
|
+
excludeSymbols: false, // disallow symbols in password(s)
|
|
325
|
+
excludeLowerChars: false, // disallow lowercase letters in password(s)
|
|
326
|
+
excludeUpperChars: false, // disallow uppercase letters in password(s)
|
|
327
|
+
similarChars: false, // include similar chars in password(s)
|
|
328
|
+
unstrict: false, // don't require 1+ char from each allowed charset in password(s)
|
|
329
|
+
entropy: false, // calculate/log estimated entropy
|
|
330
|
+
quietMode: false // suppress all logging except errors
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
💡 Run `generate-pw init` to generate a template `generate-pw.config.mjs` in your project root.
|
|
335
|
+
|
|
300
336
|
<br>
|
|
301
337
|
|
|
302
338
|
<img height=6px width="100%" src="https://assets.js-utils.org/images/separators/aqua-gradient.png?v=0d36e26">
|
package/dist/cli/index.min.js
CHANGED
|
@@ -1,21 +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/generate-pw/src
|
|
5
|
+
* Documentation: https://github.com/adamlui/js-utils/tree/main/generate-pw/docs
|
|
6
6
|
*/
|
|
7
|
-
(async()=>{globalThis.env={
|
|
8
|
-
${
|
|
9
|
-
${c.br}${app.msgs.prefix_error}: Arg [${s}] ${app.msgs.error_notRecognized}.`+c.nc),console.info(`
|
|
10
|
-
${c.by}${app.msgs.info_validArgs}.`+c.nc),g(["paramOptions","flags","infoCmds"]),process.exit(1)))});for(e of["length","qty"])app.config[e]&&(isNaN(app.config[e])||app.config[e]<1)&&(console.error(`
|
|
11
|
-
${c.br}${app.msgs.prefix_error}: [${e}] ${app.msgs.error_nonPositiveNum}.`+c.nc),l(),process.exit(1));if(process.argv.some(e=>app.regex.infoCmds.help.test(e)))g();else if(process.argv.some(e=>app.regex.infoCmds.version.test(e))){r=p(`npm view ${JSON.stringify(app.name)} version`).toString().trim()||"none";let e,s=process.cwd();for(;"/"!=s;){var t=i.join(s,"package.json");if(a.existsSync(t)){t=require(t);e=(t.dependencies?.[app.name]||t.devDependencies?.[app.name])?.match(app.regex.version)?.[1]||"none";break}s=i.dirname(s)}console.info(`
|
|
12
|
-
${app.msgs.prefix_globalVer}: `+r),console.info(app.msgs.prefix_localVer+": "+e)}else{n=o({length:app.config.length||8,qty:app.config.qty||1,charset:app.config.charset,exclude:app.config.excludeChars,numbers:!!app.config.includeNums,symbols:!!app.config.includeSymbols,lowercase:!app.config.excludeLowerChars,uppercase:!app.config.excludeUpperChars,excludeSimilarChars:!!app.config.excludeSimilarChars,strict:!!app.config.strictMode,verbose:!app.config.quietMode});p=`
|
|
13
|
-
${app.msgs.info_copying}...`,app.config.quietMode||console.info(p),s.writeSync([].concat(n).join("\n"))}function l(){console.info(`
|
|
14
|
-
${app.msgs.info_moreHelp}, ${app.msgs.info_type} ${app.name} --help' ${app.msgs.info_or} ${app.msgs.info_visit}
|
|
15
|
-
`+c.bw+app.urls.docs+c.nc)}function g(e=["header","usage","paramOptions","flags","infoCmds"]){app.prefix=""+c.btBG+c.blk+`[30m ${app.name} ${c.nc} `;let s={header:[`
|
|
16
|
-
├ ${app.prefix}${app.msgs.appCopyright||`© ${app.copyrightYear} ${app.author} under the ${app.license} license`}.`,""+app.prefix+app.msgs.prefix_source+": "+app.urls.src],usage:[`
|
|
17
|
-
${c.bw}o ${app.msgs.helpSection_usage}:`+c.nc,` ${c.bw}» `+c.bg+app.cmdFormat+c.nc],paramOptions:[`
|
|
18
|
-
${c.bw}o ${app.msgs.helpSection_paramOptions}:`+c.nc,` --length=n ${app.msgs.optionDesc_length}.`,` --qty=n ${app.msgs.optionDesc_qty}.`,` --charset=chars ${app.msgs.optionDesc_charset}.`,` --exclude=chars ${app.msgs.optionDesc_exclude}.`],flags:[`
|
|
19
|
-
${c.bw}o ${app.msgs.helpSection_flags}:`+c.nc,` -n, --include-numbers ${app.msgs.optionDesc_includeNums}.`,` -y, --include-symbols ${app.msgs.optionDesc_includeSymbols}.`,` -L, --no-lowercase ${app.msgs.optionDesc_noLower}.`,` -U, --no-uppercase ${app.msgs.optionDesc_noUpper}.`,` -S, --no-similar ${app.msgs.optionDesc_noSimilar}.`,` -s, --strict ${app.msgs.optionDesc_strict}.`,` -q, --quiet ${app.msgs.optionDesc_quiet}.`],infoCmds:[`
|
|
20
|
-
${c.bw}o ${app.msgs.helpSection_infoCmds}:`+c.nc," -h, --help "+app.msgs.optionDesc_help,` -v, --version ${app.msgs.optionDesc_version}.`]};e.forEach(n=>s[n]?.forEach(s=>{{var r=/header|usage/.test(n)?1:29;let p=process.stdout.columns||80,a=[],e=s.match(/\S+|\s+/g),o="";e.forEach(e=>{var s=p-(a.length?r:0);o.length+"| ".length+e.length>s&&(a.push(a.length?o.trimStart():o),o=""),o+=e}),a.push(a.length?o.trimStart():o),a.forEach((e,s)=>console.info("| "+(0==s?e:" ".repeat(r)+e)))}})),console.info(`
|
|
21
|
-
${app.msgs.info_moreHelp}, ${app.msgs.info_visit}: `+c.bw+app.urls.docs+c.nc)}})();
|
|
7
|
+
(async()=>{var e,n=process.argv.slice(2),i=(globalThis.env={debugMode:n.some(e=>/^--?debug(?:-?mode)?$/.test(e)),devMode:/[\\/]src(?:[\\/]|$)/i.test(__dirname)},require("node-clipboardy")),o=require(`../generate-pw${env.devMode?"":".min"}.js`).generatePassword,{generateRandomLang:s,getMsgs:r,getSysLang:a}=require(`./lib/language${env.devMode?"":".min"}.js`),p=require(`./lib/log${env.devMode?"":".min"}.js`),t=require(`./lib/settings${env.devMode?"":".min"}.js`);Object.assign(globalThis.app??={},require(`../${env.devMode?"../":"./data/"}app.json`)),app.msgs=await r(env.debugMode?s({excludes:["en"]}):a()),app.urls.docs+="/#-command-line-usage";for(e of n){if(t.controls.init.regex.test(e))return t.initConfigFile();if(t.controls.help.regex.test(e))return p.help();if(t.controls.version.regex.test(e))return p.version()}t.load();r={length:app.config.length,qty:app.config.qty,strength:app.config.mode,charset:app.config.charset,exclude:app.config.excludeChars,numbers:!app.config.excludeNums,symbols:!app.config.excludeSymbols,lowercase:!app.config.excludeLowerChars,uppercase:!app.config.excludeUpperChars,similarChars:app.config.similarChars,strict:!app.config.unstrict,entropy:app.config.entropy,verbose:!app.config.quietMode};i.writeSync([].concat(o(r)).join("\n")),p.ifNotQuiet(`
|
|
8
|
+
${app.msgs.info_copying}...`)})();
|
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/generate-pw/src
|
|
4
|
+
* Documentation: https://github.com/adamlui/js-utils/tree/main/generate-pw/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/generate-pw/src
|
|
4
|
+
* Documentation: https://github.com/adamlui/js-utils/tree/main/generate-pw/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}/_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,22 @@
|
|
|
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={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)},help(s=["header","usage","params","flags","cmds"]){app.prefix=""+this.colors.tlBG+this.colors.blk+`[30m ${app.name} ${this.colors.nc} `;let o={header:[`
|
|
13
|
+
├ ${app.prefix}${app.msgs.appCopyright}.`,""+app.prefix+app.msgs.prefix_source+": "+app.urls.src],usage:[`
|
|
14
|
+
${this.colors.bw}o ${app.msgs.helpSection_usage}:`+this.colors.nc,` ${this.colors.bw}» `+this.colors.bg+app.cmdFormat+this.colors.nc],params:[`
|
|
15
|
+
${this.colors.bw}o ${app.msgs.helpSection_params}:`+this.colors.nc,` --length=n ${app.msgs.optionDesc_length}.`,` --qty=n ${app.msgs.optionDesc_qty}.`,` --charset=chars ${app.msgs.optionDesc_charset}.`,` --exclude=chars ${app.msgs.optionDesc_exclude}.`,` --config="path/to/file" ${app.msgs.optionDesc_config}.`],flags:[`
|
|
16
|
+
${this.colors.bw}o ${app.msgs.helpSection_flags}:`+this.colors.nc,` -w, --weak ${app.msgs.optionDesc_weak}.`,` -b, --basic ${app.msgs.optionDesc_basic}.`,` -t, --strong ${app.msgs.optionDesc_strong}.`,` -N, --no-numbers ${app.msgs.optionDesc_excludeNums}.`,` -Y, --no-symbols ${app.msgs.optionDesc_excludeSymbols}.`,` -L, --no-lowercase ${app.msgs.optionDesc_noLower}.`,` -U, --no-uppercase ${app.msgs.optionDesc_noUpper}.`,` -s, --similar-chars ${app.msgs.optionDesc_similarChars}.`,` -S, --unstrict ${app.msgs.optionDesc_unstrict}.`,` -e, --entropy ${app.msgs.optionDesc_entropy}.`,` -q, --quiet ${app.msgs.optionDesc_quiet}.`],cmds:[`
|
|
17
|
+
${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 i=/header|usage/.test(c)?1:29;let e=process.stdout.columns||80,s=o.match(/\S+|\s+/g),p=[],r="";s.forEach(s=>{var o=e-(p.length?i:0);r.length+"| ".length+s.length>o&&(p.push(p.length?r.trimStart():r),r=""),r+=s}),p.push(p.length?r.trimStart():r),p.forEach((s,o)=>console.info("| "+(0==o?s:" ".repeat(i)+s)))}})),console.info(`
|
|
18
|
+
${app.msgs.info_moreHelp}, ${app.msgs.info_visit}: `+this.colors.bw+app.urls.docs+this.colors.nc)},helpCmdAndDocURL(){console.info(`
|
|
19
|
+
${app.msgs.info_moreHelp}, ${app.msgs.info_type} ${app.name} --help' ${app.msgs.info_or} ${app.msgs.info_visit}
|
|
20
|
+
`+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("Error reading local package version:",s.message)}console.info(`
|
|
21
|
+
${app.msgs.prefix_globalVer}: ${s}
|
|
22
|
+
${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/generate-pw/src
|
|
4
|
+
* Documentation: https://github.com/adamlui/js-utils/tree/main/generate-pw/docs
|
|
5
|
+
*/
|
|
6
|
+
let fs=require("fs"),log=require(`./log${env.devMode?"":".min"}.js`),path=require("path");(globalThis.app??={}).config={},module.exports={configFilename:"generate-pw.config.mjs",controls:{length:{type:"param",defaultVal:12,regex:/^--?length(?:=.*|$)/},qty:{type:"param",defaultVal:1,regex:/^--?qu?a?n?ti?t?y(?:=.*|$)/},weak:{type:"flag",mode:!0,regex:/^--?weak$/},basic:{type:"flag",mode:!0,regex:/^--?basic$/},strong:{type:"flag",mode:!0,regex:/^--?strong$/},charset:{type:"param",regex:/^--?charse?t?(?:=.*|$)/},excludeChars:{type:"param",regex:/^--?exclude(?:=.*|$)/},config:{type:"param",regex:/^--?config(?:=.*|$)/},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(r=this.configFilename){var e=path.resolve(process.cwd(),r);if(fs.existsSync(e))return log.warn(app.msgs.warn_configFileExists+":",e);var s=path.resolve(__dirname,"../../"+(env.devMode?"../":"./data/")+r);if(fs.existsSync(s))fs.copyFileSync(s,e);else{s=require(`./data${env.devMode?"":".min"}.js`),r=app.urls.jsdelivr+"/generate-pw/"+r;log.data(app.msgs.info_fetchingRemoteConfigFrom+` ${r}...`);try{var t=await s.fetch(r);if(!t.ok)return log.warn(`${app.msgs.warn_remoteConfigNotFound}: ${r} (${t.status})`);s.atomicWrite(e,await t.text())}catch(e){return log.warn(app.msgs.warn_remoteConfigFailed+`: ${r} `+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:a=Object.keys(this.controls)}={}){a.forEach(e=>{var r=this.controls[e];r.mode||"cmd"==r.type||(app.config[e]??=r.defaultVal??("flag"!=r.type&&""))});let r=null;var s=e.find(e=>this.controls.config.regex.test(e));if(s){/=/.test(s)||log.errorAndExit(`[${s}] `+app.msgs.error_mustIncludePath);s=s.split("=")[1];r=path.isAbsolute(s)?s:path.resolve(process.cwd(),s),fs.existsSync(r)||log.configURLandExit(app.msgs.error_configFileNotFound+":",r)}else for(var t of["mjs","cjs","js"]){t=path.resolve(process.cwd(),this.configFilename.replace(/\.[^.]+$/,"."+t));if(fs.existsSync(t)){r=t;break}}if(r)try{var o=require(r),i=o?.default??o;i&&"object"==typeof i||log.configURLandExit(app.msgs.error_invalidConfigFile+"."),Object.assign(app.config,i)}catch(e){log.configURLandExit(app.msgs.error_failedToLoadConfigFile+":",r,`
|
|
8
|
+
`+e.message)}return e.forEach(r=>{if(!/^[^-]|--?(?:config|debug)/.test(r)){var s=a.find(e=>this.controls[e]?.regex?.test(r)),t=(s||log.errorAndExit(`[${r}] ${app.msgs.error_notRecognized}.`),this.controls[s]);if("cmd"!=t.type){let e="param"!=t.type||r.split("=")[1]?.trim();t.mode?app.config.mode=s.replace(/mode$/i,"").toLowerCase():((t=t.parser)&&(e=t(e),isNaN(e)||e<1)&&log.errorAndExit(`[${s}] ${app.msgs.error_nonPositiveNum}.`),app.config[s]=e)}}}),app.config}};
|
package/dist/data/app.json
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
"copyrightYear": "2024–2026",
|
|
6
6
|
"cmdFormat": "generate-pw [options|commands]",
|
|
7
7
|
"urls": {
|
|
8
|
+
"config": "https://github.com/adamlui/js-utils/blob/main/generate-pw/generate-pw.config.mjs",
|
|
8
9
|
"docs": "https://github.com/adamlui/js-utils/tree/main/generate-pw/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/generate-pw/src"
|
|
13
14
|
},
|
|
14
15
|
"commitHashes": {
|
|
15
|
-
"locales": "
|
|
16
|
+
"locales": "4bade59"
|
|
16
17
|
}
|
|
17
18
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* generate-pw.config.mjs
|
|
3
|
+
*
|
|
4
|
+
* Optional config file for the generate-pw 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/generate-pw/#-command-line-usage
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export default {
|
|
12
|
+
|
|
13
|
+
// Size params
|
|
14
|
+
length: 12, // length of passwords to generate
|
|
15
|
+
qty: 1, // # of passwords to generate
|
|
16
|
+
|
|
17
|
+
// Generator options
|
|
18
|
+
strength: '', // <'weak'|'basic'|'strong'> apply strength preset
|
|
19
|
+
excludeNums: false, // disallow numbers in password(s)
|
|
20
|
+
excludeSymbols: false, // disallow symbols in password(s)
|
|
21
|
+
excludeLowerChars: false, // disallow lowercase letters in password(s)
|
|
22
|
+
excludeUpperChars: false, // disallow uppercase letters in password(s)
|
|
23
|
+
similarChars: false, // include similar chars (e.g. o,0,O,i,l,1,\|) in password(s)
|
|
24
|
+
unstrict: false, // don't require 1+ char from each allowed charset in password(s)
|
|
25
|
+
charset: '', // only include chars in password(s)
|
|
26
|
+
exclude: '', // exclude chars from password(s)
|
|
27
|
+
|
|
28
|
+
// Info options
|
|
29
|
+
entropy: false, // calculate/log estimated entropy
|
|
30
|
+
quietMode: false // suppress all logging except errors
|
|
31
|
+
}
|
package/dist/data/messages.json
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
"appName": { "message": "generate-pw" },
|
|
3
3
|
"appCopyright": { "message": "© 2024–2026 Adam Lui & contributors 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" },
|
|
@@ -9,27 +11,44 @@
|
|
|
9
11
|
"error_notRecognized": { "message": "not recognized" },
|
|
10
12
|
"error_nonPositiveNum": { "message": "argument can only be > 0" },
|
|
11
13
|
"error_invalidURL": { "message": "Invalid URL" },
|
|
12
|
-
"
|
|
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" },
|
|
13
20
|
"info_copying": { "message": "Copying to clipboard" },
|
|
14
21
|
"info_moreHelp": { "message": "For more help" },
|
|
15
22
|
"info_type": { "message": "type" },
|
|
16
23
|
"info_or": { "message": "or" },
|
|
17
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": "Remote config file not found" },
|
|
29
|
+
"tip_editToSetDefaults": { "message": "Edit this file to customize defaults" },
|
|
30
|
+
"tip_cliArgsPrioritized": { "message": "CLI arguments always override these values" },
|
|
18
31
|
"helpSection_usage": { "message": "Usage" },
|
|
19
|
-
"
|
|
32
|
+
"helpSection_params": { "message": "Parameter options" },
|
|
20
33
|
"helpSection_flags": { "message": "Boolean options" },
|
|
21
|
-
"
|
|
34
|
+
"helpSection_cmds": { "message": "Commands" },
|
|
22
35
|
"optionDesc_length": { "message": "Generate password(s) of n length" },
|
|
23
36
|
"optionDesc_qty": { "message": "Generate n password(s)" },
|
|
37
|
+
"optionDesc_config": { "message": "Load custom config file" },
|
|
24
38
|
"optionDesc_charset": { "message": "Only include chars in password(s)" },
|
|
25
39
|
"optionDesc_exclude": { "message": "Exclude chars from password(s)" },
|
|
26
|
-
"
|
|
27
|
-
"
|
|
40
|
+
"optionDesc_weak": { "message": "Generate weak password(s)" },
|
|
41
|
+
"optionDesc_basic": { "message": "Generate basic strength password(s)" },
|
|
42
|
+
"optionDesc_strong": { "message": "Generate strong password(s)" },
|
|
43
|
+
"optionDesc_excludeNums": { "message": "Disallow numbers in password(s)" },
|
|
44
|
+
"optionDesc_excludeSymbols": { "message": "Disallow symbols in password(s)" },
|
|
28
45
|
"optionDesc_noLower": { "message": "Disallow lowercase letters in password(s)" },
|
|
29
46
|
"optionDesc_noUpper": { "message": "Disallow uppercase letters in password(s)" },
|
|
30
|
-
"
|
|
31
|
-
"
|
|
47
|
+
"optionDesc_similarChars": { "message": "Include similar characters in password(s)" },
|
|
48
|
+
"optionDesc_unstrict": { "message": "Don't require at least one character from each allowed character set in password(s)" },
|
|
49
|
+
"optionDesc_entropy": { "message": "Calculate/log estimated entropy" },
|
|
32
50
|
"optionDesc_quiet": { "message": "Suppress all logging except errors" },
|
|
33
51
|
"optionDesc_help": { "message": "Display help screen" },
|
|
52
|
+
"optionDesc_init": { "message": "Create config file (in project root)" },
|
|
34
53
|
"optionDesc_version": { "message": "Show version number" }
|
|
35
54
|
}
|
package/dist/generate-pw.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/generate-pw/src
|
|
4
|
+
* Documentation: https://github.com/adamlui/js-utils/tree/main/generate-pw/docs
|
|
5
5
|
*/
|
|
6
|
-
|
|
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=app.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?app.charsets.numbers:"")+(s.symbols?app.charsets.symbols:"")+(s.lowercase?app.charsets.lower:"")+(s.uppercase?app.charsets.upper:""),t=(""==r&&(r=app.charsets.lower+app.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=app.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]&&app.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=app.charsets[p]||app.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))(app.charsets[i]||app.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.app??={},{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: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 r=Object.keys(e).join(", "),e=JSON.stringify(e,void 0,2).replace(/"([^"]+)":/g,"$1:").replace(/"/g,"'").replace(/\n\s*/g," ");this.info(`Valid options: [${r}]`),this.info("If omitted, default settings are: "+e)}};app.exports={generatePassword:generatePassword,generatePasswords:generatePasswords,strictify:strictify,validateStrength:validateStrength};try{module.exports={...app.exports}}catch(e){}try{window.pw={...app.exports}}catch(e){}for(let r in app.aliases){try{app.aliases[r].forEach(e=>module.exports[e]??=module.exports[r])}catch(e){}try{app.aliases[r].forEach(e=>window.pw[e]??=window.pw[r])}catch(e){}}
|
package/docs/README.md
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
<a id="top"></a>
|
|
2
2
|
|
|
3
|
-
<a id="top"></a>
|
|
4
|
-
|
|
5
3
|
<div align="right">
|
|
6
4
|
<h6>
|
|
7
5
|
<picture>
|
|
@@ -27,12 +25,12 @@
|
|
|
27
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>
|
|
28
26
|
<a href="#%EF%B8%8F-mit-license">
|
|
29
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>
|
|
30
|
-
<a href="https://github.com/adamlui/js-utils/releases/tag/generate-pw-
|
|
31
|
-
<img height=31 src="https://img.shields.io/badge/Latest_Build-
|
|
28
|
+
<a href="https://github.com/adamlui/js-utils/releases/tag/generate-pw-2.0.0">
|
|
29
|
+
<img height=31 src="https://img.shields.io/badge/Latest_Build-2.0.0-44cc11.svg?logo=icinga&logoColor=white&labelColor=464646&style=for-the-badge"></a>
|
|
32
30
|
<a href="https://www.npmjs.com/package/generate-pw?activeTab=code">
|
|
33
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>
|
|
34
|
-
<a href="https://github.com/adamlui/js-utils/blob/generate-pw-
|
|
35
|
-
<img height=31 src="https://img.shields.io/github/size/adamlui/js-utils/generate-pw/dist/generate-pw.min.js?branch=generate-pw-
|
|
32
|
+
<a href="https://github.com/adamlui/js-utils/blob/generate-pw-2.0.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.0.0&label=Minified%20Size&logo=databricks&logoColor=white&labelColor=464646&color=ff69b4&style=for-the-badge"></a>
|
|
36
34
|
<a href="https://sonarcloud.io/component_measures?metric=new_vulnerabilities&id=adamlui_js-utils:generate-pw/src/generate-pw.js">
|
|
37
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>
|
|
38
36
|
<a href="https://github.com/toolleeo/cli-apps#password-managers">
|
|
@@ -80,7 +78,7 @@ $ npm install generate-pw
|
|
|
80
78
|
#### ECMAScript*:
|
|
81
79
|
|
|
82
80
|
```js
|
|
83
|
-
import pw from 'generate-pw'
|
|
81
|
+
import pw from 'generate-pw'
|
|
84
82
|
```
|
|
85
83
|
|
|
86
84
|
#### CommonJS:
|
|
@@ -96,14 +94,14 @@ const pw = require('generate-pw')
|
|
|
96
94
|
#### <> HTML script tag:
|
|
97
95
|
|
|
98
96
|
```html
|
|
99
|
-
<script src="https://cdn.jsdelivr.net/npm/generate-pw@
|
|
97
|
+
<script src="https://cdn.jsdelivr.net/npm/generate-pw@2.0.0/dist/generate-pw.min.js"></script>
|
|
100
98
|
```
|
|
101
99
|
|
|
102
100
|
#### ES6:
|
|
103
101
|
|
|
104
102
|
```js
|
|
105
103
|
(async () => {
|
|
106
|
-
await import('https://cdn.jsdelivr.net/npm/generate-pw@
|
|
104
|
+
await import('https://cdn.jsdelivr.net/npm/generate-pw@2.0.0/dist/generate-pw.min.js')
|
|
107
105
|
// Your code here...
|
|
108
106
|
})()
|
|
109
107
|
```
|
|
@@ -112,7 +110,7 @@ const pw = require('generate-pw')
|
|
|
112
110
|
|
|
113
111
|
```js
|
|
114
112
|
...
|
|
115
|
-
// @require https://cdn.jsdelivr.net/npm/generate-pw@
|
|
113
|
+
// @require https://cdn.jsdelivr.net/npm/generate-pw@2.0.0/dist/generate-pw.min.js
|
|
116
114
|
// ==/UserScript==
|
|
117
115
|
|
|
118
116
|
// Your code here...
|
|
@@ -120,7 +118,7 @@ const pw = require('generate-pw')
|
|
|
120
118
|
|
|
121
119
|
<br>
|
|
122
120
|
|
|
123
|
-
**💡 Note:** To always import the latest version (not recommended in production!) remove the `@
|
|
121
|
+
**💡 Note:** To always import the latest version (not recommended in production!) remove the `@2.0.0` version tag from the jsDelivr URL: `https://cdn.jsdelivr.net/npm/generate-pw/dist/generate-pw.min.js`
|
|
124
122
|
|
|
125
123
|
<br>
|
|
126
124
|
|
|
@@ -192,7 +190,7 @@ console.log(strictPW) // sample output: 'a!c2ef'
|
|
|
192
190
|
|
|
193
191
|
**💡 Note:** If no `requiredCharTypes` array is passed, all available types will be required.
|
|
194
192
|
|
|
195
|
-
Available `requiredCharTypes` are: `['
|
|
193
|
+
Available `requiredCharTypes` are: `['numbers', 'symbols', 'lower', 'upper']`
|
|
196
194
|
|
|
197
195
|
Available options (passed as object properties):
|
|
198
196
|
|
|
@@ -247,15 +245,17 @@ Name | Type | Description
|
|
|
247
245
|
----------------------|---------|--------------------------------------------------------------------------------|---------------
|
|
248
246
|
`verbose` | Boolean | Show logging in console/terminal. | `true`
|
|
249
247
|
`length` | Integer | Length of password(s). | `8`
|
|
250
|
-
`qty
|
|
248
|
+
`qty` | Integer | Number of passwords to generate. | `1`
|
|
249
|
+
`strength` | String | `<'weak'\|'basic'\|'strong'>` Apply strength preset. | `''`
|
|
251
250
|
`charset` | String | Characters to include in password(s). | `''`
|
|
252
251
|
`exclude` | String | Characters to exclude from password(s). | `''`
|
|
253
252
|
`numbers` | Boolean | Allow numbers in password(s). | `false`
|
|
254
253
|
`symbols` | Boolean | Allow symbols in password(s). | `false`
|
|
255
254
|
`lowercase` | Boolean | Allow lowercase letters in password(s). | `true`
|
|
256
255
|
`uppercase` | Boolean | Allow uppercase letters in password(s). | `true`
|
|
257
|
-
`
|
|
258
|
-
`strict` | Boolean | Require at least one character from each allowed character set in password(s). | `
|
|
256
|
+
`similarChars` | Boolean | Include similar characters (e.g. o,0,O,i,l,1,\|) in password(s). | `false`
|
|
257
|
+
`strict` | Boolean | Require at least one character from each allowed character set in password(s). | `true`
|
|
258
|
+
`entropy` | Boolean | Calculate/log estimated entropy. | `false`
|
|
259
259
|
|
|
260
260
|
##### _*Only available in [`generatePassword([options])`](#generatepasswordoptions) since [`generatePasswords(qty[, options])`](#generatepasswordsqty-options) takes a `qty` argument_
|
|
261
261
|
|
|
@@ -283,22 +283,56 @@ Parameter options:
|
|
|
283
283
|
--qty=n Generate n password(s).
|
|
284
284
|
--charset=chars Only include chars in password(s).
|
|
285
285
|
--exclude=chars Exclude chars from password(s).
|
|
286
|
+
--config="path/to/file" Load custom config file.
|
|
286
287
|
|
|
287
288
|
Boolean options:
|
|
288
|
-
-
|
|
289
|
-
-
|
|
289
|
+
-w, --weak Generate weak password(s).
|
|
290
|
+
-b, --basic Generate basic strength password(s).
|
|
291
|
+
-t, --strong Generate strong password(s).
|
|
292
|
+
-N, --no-numbers Disallow numbers in password(s).
|
|
293
|
+
-Y, --no-symbols Disallow symbols in password(s).
|
|
290
294
|
-L, --no-lowercase Disallow lowercase letters in password(s).
|
|
291
295
|
-U, --no-uppercase Disallow uppercase letters in password(s).
|
|
292
|
-
-S, --
|
|
293
|
-
-
|
|
294
|
-
allowed character set in password(s).
|
|
296
|
+
-S, --similar-chars Include similar characters in password(s).
|
|
297
|
+
-S, --unstrict Don't require at least one character from
|
|
298
|
+
each allowed character set in password(s).
|
|
299
|
+
-e, --entropy Calculate/log estimated entropy.
|
|
295
300
|
-q, --quiet Suppress all logging except errors.
|
|
296
301
|
|
|
297
|
-
|
|
302
|
+
Commands:
|
|
303
|
+
-i, --init Create config file (in project root).
|
|
298
304
|
-h, --help Display help screen.
|
|
299
305
|
-v, --version Show version number.
|
|
300
306
|
```
|
|
301
307
|
|
|
308
|
+
#
|
|
309
|
+
|
|
310
|
+
### Configuration file
|
|
311
|
+
|
|
312
|
+
**generate-pw** can be customized using a `generate-pw.config.mjs` or `generate-pw.config.js` placed in your project root.
|
|
313
|
+
|
|
314
|
+
Example defaults:
|
|
315
|
+
|
|
316
|
+
```js
|
|
317
|
+
export default {
|
|
318
|
+
length: 12, // length of passwords to generate
|
|
319
|
+
qty: 1, // # of passwords to generate
|
|
320
|
+
strength: '', // <'weak'|'basic'|'strong'> apply strength preset
|
|
321
|
+
charset: '', // only include chars in password(s)
|
|
322
|
+
exclude: '', // exclude chars from password(s)
|
|
323
|
+
excludeNums: false, // disallow numbers in password(s)
|
|
324
|
+
excludeSymbols: false, // disallow symbols in password(s)
|
|
325
|
+
excludeLowerChars: false, // disallow lowercase letters in password(s)
|
|
326
|
+
excludeUpperChars: false, // disallow uppercase letters in password(s)
|
|
327
|
+
similarChars: false, // include similar chars in password(s)
|
|
328
|
+
unstrict: false, // don't require 1+ char from each allowed charset in password(s)
|
|
329
|
+
entropy: false, // calculate/log estimated entropy
|
|
330
|
+
quietMode: false // suppress all logging except errors
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
💡 Run `generate-pw init` to generate a template `generate-pw.config.mjs` in your project root.
|
|
335
|
+
|
|
302
336
|
<br>
|
|
303
337
|
|
|
304
338
|
<img height=6px width="100%" src="https://assets.js-utils.org/images/separators/aqua-gradient.png?v=0d36e26">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "generate-pw",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Randomly generate, strengthen, and validate cryptographically-secure passwords.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Adam Lui",
|
|
@@ -42,7 +42,12 @@
|
|
|
42
42
|
"doc": "./docs"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
|
-
"build": "
|
|
45
|
+
"build": "node utils/build",
|
|
46
|
+
"build:js": "node utils/build --js",
|
|
47
|
+
"build:data": "node utils/build --data",
|
|
48
|
+
"build:json": "node utils/build --json",
|
|
49
|
+
"debug": "node src/cli --debug",
|
|
50
|
+
"translate": "py utils/translate-en-messages.py",
|
|
46
51
|
"bump:patch": "bash utils/bump.sh patch",
|
|
47
52
|
"bump:minor": "bash utils/bump.sh minor",
|
|
48
53
|
"bump:major": "bash utils/bump.sh major"
|
|
@@ -62,10 +67,10 @@
|
|
|
62
67
|
"bugs": {
|
|
63
68
|
"url": "https://github.com/adamlui/js-utils/issues"
|
|
64
69
|
},
|
|
65
|
-
"devDependencies": {
|
|
66
|
-
"@adamlui/minify.js": "^2.1.3"
|
|
67
|
-
},
|
|
68
70
|
"dependencies": {
|
|
69
71
|
"node-clipboardy": "^1.0.3"
|
|
72
|
+
},
|
|
73
|
+
"devDependencies": {
|
|
74
|
+
"@adamlui/minify.js": "^2.2.0"
|
|
70
75
|
}
|
|
71
76
|
}
|