js-generate-password 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +280 -172
- package/dist/index.cjs +202 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.cts +67 -0
- package/dist/index.d.mts +67 -0
- package/dist/index.d.ts +65 -1
- package/dist/index.mjs +176 -0
- package/dist/index.mjs.map +7 -0
- package/package.json +59 -51
- package/src/index.ts +22 -0
- package/src/lib/check-options-error.ts +52 -0
- package/src/lib/generate-random-number.ts +48 -0
- package/src/lib/password-generator.ts +92 -0
- package/src/lib/process-options.ts +34 -0
- package/src/lib/shuffle-string.ts +21 -0
- package/src/types.ts +57 -0
- package/dist/index.js +0 -1
- package/dist/lib/check-options-error.d.ts +0 -2
- package/dist/lib/generate-random-number.d.ts +0 -1
- package/dist/lib/password-generator.d.ts +0 -2
- package/dist/lib/process-options.d.ts +0 -2
- package/dist/lib/shuffle-string.d.ts +0 -1
- package/dist/types.d.ts +0 -58
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* js-generate-password v1.1.0
|
|
3
|
+
* Tiny, dependency-free, cryptographically secure password generator for JavaScript and TypeScript projects.
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
"use strict";
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
10
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
11
|
+
var __export = (target, all) => {
|
|
12
|
+
for (var name in all)
|
|
13
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
14
|
+
};
|
|
15
|
+
var __copyProps = (to, from, except, desc) => {
|
|
16
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
17
|
+
for (let key of __getOwnPropNames(from))
|
|
18
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
19
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
24
|
+
|
|
25
|
+
// src/index.ts
|
|
26
|
+
var index_exports = {};
|
|
27
|
+
__export(index_exports, {
|
|
28
|
+
GeneratePassword: () => GeneratePassword,
|
|
29
|
+
default: () => index_default
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(index_exports);
|
|
32
|
+
|
|
33
|
+
// src/lib/generate-random-number.ts
|
|
34
|
+
var UINT32_RANGE = 4294967296;
|
|
35
|
+
var getWebCrypto = () => {
|
|
36
|
+
const webCrypto = globalThis.crypto;
|
|
37
|
+
if (!webCrypto || typeof webCrypto.getRandomValues !== "function") {
|
|
38
|
+
throw new Error(
|
|
39
|
+
"js-generate-password: no Web Crypto implementation found. A secure random source is required to generate passwords. Use Node.js 18+, a modern browser, or polyfill `globalThis.crypto`."
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
return webCrypto;
|
|
43
|
+
};
|
|
44
|
+
var generateRandomNumbers = (upperLimit) => {
|
|
45
|
+
if (!Number.isInteger(upperLimit) || upperLimit <= 0) {
|
|
46
|
+
throw new RangeError(
|
|
47
|
+
`js-generate-password: upperLimit must be a positive integer, received ${upperLimit}.`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
const webCrypto = getWebCrypto();
|
|
51
|
+
const buffer = new Uint32Array(1);
|
|
52
|
+
const cutoff = Math.floor(UINT32_RANGE / upperLimit) * upperLimit;
|
|
53
|
+
let value;
|
|
54
|
+
do {
|
|
55
|
+
webCrypto.getRandomValues(buffer);
|
|
56
|
+
value = buffer[0];
|
|
57
|
+
} while (value >= cutoff);
|
|
58
|
+
return value % upperLimit;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// src/lib/shuffle-string.ts
|
|
62
|
+
var shuffleString = (str) => {
|
|
63
|
+
const chars = [...str];
|
|
64
|
+
for (let i = chars.length - 1; i > 0; i--) {
|
|
65
|
+
const j = generateRandomNumbers(i + 1);
|
|
66
|
+
const tmp = chars[i];
|
|
67
|
+
chars[i] = chars[j];
|
|
68
|
+
chars[j] = tmp;
|
|
69
|
+
}
|
|
70
|
+
return chars.join("");
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
// src/lib/password-generator.ts
|
|
74
|
+
var LOWERCASE_CHARS = "abcdefghijklmnopqrstuvwxyz";
|
|
75
|
+
var UPPERCASE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
76
|
+
var NUMBER_CHARS = "0123456789";
|
|
77
|
+
var SYMBOL_CHARS = "!#$%&'()*+,-./:;<=>?@[]^_{|}~";
|
|
78
|
+
var removeExceptions = (str, exclude) => {
|
|
79
|
+
if (!exclude) return str;
|
|
80
|
+
const banned = /* @__PURE__ */ new Set([...exclude]);
|
|
81
|
+
return [...str].filter((char) => !banned.has(char)).join("");
|
|
82
|
+
};
|
|
83
|
+
var pickFrom = (pool, count, name) => {
|
|
84
|
+
if (count === 0) return "";
|
|
85
|
+
if (pool.length === 0) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
`js-generate-password: \`exclude\` removed every ${name} character, but \`minLength${name[0].toUpperCase()}${name.slice(1)}\` is ${count}.`
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
let picked = "";
|
|
91
|
+
for (let i = 0; i < count; i++) {
|
|
92
|
+
picked += pool.charAt(generateRandomNumbers(pool.length));
|
|
93
|
+
}
|
|
94
|
+
return picked;
|
|
95
|
+
};
|
|
96
|
+
var generatePswd = (options) => {
|
|
97
|
+
const {
|
|
98
|
+
length,
|
|
99
|
+
lowercase,
|
|
100
|
+
uppercase,
|
|
101
|
+
numbers,
|
|
102
|
+
symbols,
|
|
103
|
+
minLengthLowercase,
|
|
104
|
+
minLengthUppercase,
|
|
105
|
+
minLengthNumbers,
|
|
106
|
+
minLengthSymbols,
|
|
107
|
+
exclude
|
|
108
|
+
} = options;
|
|
109
|
+
const lowercaseChar = removeExceptions(LOWERCASE_CHARS, exclude);
|
|
110
|
+
const uppercaseChar = removeExceptions(UPPERCASE_CHARS, exclude);
|
|
111
|
+
const numberChar = removeExceptions(NUMBER_CHARS, exclude);
|
|
112
|
+
const symbolChar = removeExceptions(SYMBOL_CHARS, exclude);
|
|
113
|
+
const guaranteed = pickFrom(lowercaseChar, minLengthLowercase, "lowercase") + pickFrom(uppercaseChar, minLengthUppercase, "uppercase") + pickFrom(numberChar, minLengthNumbers, "numbers") + pickFrom(symbolChar, minLengthSymbols, "symbols");
|
|
114
|
+
const characterPool = (lowercase ? lowercaseChar : "") + (uppercase ? uppercaseChar : "") + (numbers ? numberChar : "") + (symbols ? symbolChar : "");
|
|
115
|
+
const remaining = length - guaranteed.length;
|
|
116
|
+
if (remaining > 0 && characterPool.length === 0) {
|
|
117
|
+
throw new Error(
|
|
118
|
+
"js-generate-password: `exclude` removed every character of every enabled class. No valid characters to generate the password from."
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
let filler = "";
|
|
122
|
+
for (let i = 0; i < remaining; i++) {
|
|
123
|
+
filler += characterPool.charAt(generateRandomNumbers(characterPool.length));
|
|
124
|
+
}
|
|
125
|
+
return shuffleString(guaranteed + filler);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// src/lib/check-options-error.ts
|
|
129
|
+
var assertCount = (value, name) => {
|
|
130
|
+
if (!Number.isInteger(value) || value < 0) {
|
|
131
|
+
throw new Error(
|
|
132
|
+
`js-generate-password: \`${name}\` must be a non-negative integer, received ${value}.`
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
var checkError = (options) => {
|
|
137
|
+
const {
|
|
138
|
+
length,
|
|
139
|
+
lowercase,
|
|
140
|
+
uppercase,
|
|
141
|
+
numbers,
|
|
142
|
+
symbols,
|
|
143
|
+
minLengthLowercase,
|
|
144
|
+
minLengthUppercase,
|
|
145
|
+
minLengthNumbers,
|
|
146
|
+
minLengthSymbols
|
|
147
|
+
} = options;
|
|
148
|
+
if (!Number.isInteger(length) || length < 1) {
|
|
149
|
+
throw new Error(
|
|
150
|
+
`js-generate-password: \`length\` must be a positive integer, received ${length}.`
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
assertCount(minLengthLowercase, "minLengthLowercase");
|
|
154
|
+
assertCount(minLengthUppercase, "minLengthUppercase");
|
|
155
|
+
assertCount(minLengthNumbers, "minLengthNumbers");
|
|
156
|
+
assertCount(minLengthSymbols, "minLengthSymbols");
|
|
157
|
+
if (!lowercase && !uppercase && !numbers && !symbols) {
|
|
158
|
+
throw new Error(
|
|
159
|
+
"js-generate-password: `lowercase`, `uppercase`, `numbers` and `symbols` are all false. No valid characters to generate the password from."
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
const minimumTotal = minLengthLowercase + minLengthUppercase + minLengthNumbers + minLengthSymbols;
|
|
163
|
+
if (minimumTotal > length) {
|
|
164
|
+
throw new Error(
|
|
165
|
+
`js-generate-password: the sum of the minimum character counts (${minimumTotal}) is greater than \`length\` (${length}).`
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
// src/lib/process-options.ts
|
|
171
|
+
var withDefault = (value, fallback) => typeof value === "undefined" ? fallback : value;
|
|
172
|
+
var processOption = (options) => {
|
|
173
|
+
const lowercase = withDefault(options.lowercase, true);
|
|
174
|
+
const uppercase = withDefault(options.uppercase, true);
|
|
175
|
+
const numbers = withDefault(options.numbers, true);
|
|
176
|
+
const symbols = withDefault(options.symbols, false);
|
|
177
|
+
return {
|
|
178
|
+
length: withDefault(options.length, 10),
|
|
179
|
+
lowercase,
|
|
180
|
+
uppercase,
|
|
181
|
+
numbers,
|
|
182
|
+
symbols,
|
|
183
|
+
exclude: withDefault(options.exclude, ""),
|
|
184
|
+
minLengthLowercase: lowercase ? withDefault(options.minLengthLowercase, 1) : 0,
|
|
185
|
+
minLengthUppercase: uppercase ? withDefault(options.minLengthUppercase, 1) : 0,
|
|
186
|
+
minLengthNumbers: numbers ? withDefault(options.minLengthNumbers, 1) : 0,
|
|
187
|
+
minLengthSymbols: symbols ? withDefault(options.minLengthSymbols, 1) : 0
|
|
188
|
+
};
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
// src/index.ts
|
|
192
|
+
function GeneratePassword(options = {}) {
|
|
193
|
+
const resolved = processOption(options);
|
|
194
|
+
checkError(resolved);
|
|
195
|
+
return generatePswd(resolved);
|
|
196
|
+
}
|
|
197
|
+
var index_default = GeneratePassword;
|
|
198
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
199
|
+
0 && (module.exports = {
|
|
200
|
+
GeneratePassword
|
|
201
|
+
});
|
|
202
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts", "../src/lib/generate-random-number.ts", "../src/lib/shuffle-string.ts", "../src/lib/password-generator.ts", "../src/lib/check-options-error.ts", "../src/lib/process-options.ts"],
|
|
4
|
+
"sourcesContent": ["import { generatePswd } from './lib/password-generator'\nimport { checkError } from './lib/check-options-error'\nimport { processOption } from './lib/process-options'\nimport { GenerateOptions } from './types'\n\n/**\n * Generates a random password using a cryptographically secure random source.\n *\n * @param options - Optional overrides. Every unset option falls back to its\n * documented default.\n * @returns The generated password.\n */\nfunction GeneratePassword(options: GenerateOptions = {}): string {\n const resolved = processOption(options)\n\n checkError(resolved)\n\n return generatePswd(resolved)\n}\n\nexport { GeneratePassword, type GenerateOptions }\nexport default GeneratePassword\n", "/**\n * Number of distinct values a Uint32 can hold.\n */\nconst UINT32_RANGE = 0x100000000\n\nconst getWebCrypto = (): Crypto => {\n const webCrypto = globalThis.crypto\n\n if (!webCrypto || typeof webCrypto.getRandomValues !== 'function') {\n throw new Error(\n 'generate-password-lite: no Web Crypto implementation found. ' +\n 'A secure random source is required to generate passwords. ' +\n 'Use Node.js 18+, a modern browser, or polyfill `globalThis.crypto`.'\n )\n }\n\n return webCrypto\n}\n\n/**\n * Returns a cryptographically secure integer in the range [0, upperLimit).\n *\n * Uses rejection sampling so that every value is equally likely. Taking a\n * plain `random % upperLimit` would bias the low end of the range whenever\n * `upperLimit` is not a power of two.\n */\nexport const generateRandomNumbers = (upperLimit: number): number => {\n if (!Number.isInteger(upperLimit) || upperLimit <= 0) {\n throw new RangeError(\n `generate-password-lite: upperLimit must be a positive integer, received ${upperLimit}.`\n )\n }\n\n const webCrypto = getWebCrypto()\n const buffer = new Uint32Array(1)\n\n // Largest multiple of upperLimit that fits in the Uint32 range. Draws at or\n // above this cutoff are discarded rather than folded back into the range.\n const cutoff = Math.floor(UINT32_RANGE / upperLimit) * upperLimit\n\n let value: number\n do {\n webCrypto.getRandomValues(buffer)\n value = buffer[0]!\n } while (value >= cutoff)\n\n return value % upperLimit\n}\n", "import { generateRandomNumbers } from './generate-random-number'\n\n/**\n * Fisher-Yates shuffle backed by the same cryptographically secure source\n * used to pick the characters themselves.\n *\n * Spreads across code points rather than UTF-16 units so that a surrogate\n * pair supplied through `exclude` handling is never split in half.\n */\nexport const shuffleString = (str: string): string => {\n const chars = [...str]\n\n for (let i = chars.length - 1; i > 0; i--) {\n const j = generateRandomNumbers(i + 1)\n const tmp = chars[i]!\n chars[i] = chars[j]!\n chars[j] = tmp\n }\n\n return chars.join('')\n}\n", "import { generateRandomNumbers } from './generate-random-number'\nimport { shuffleString } from './shuffle-string'\nimport { ResolvedOptions } from '../types'\n\nconst LOWERCASE_CHARS = 'abcdefghijklmnopqrstuvwxyz'\nconst UPPERCASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'\nconst NUMBER_CHARS = '0123456789'\nconst SYMBOL_CHARS = \"!#$%&'()*+,-./:;<=>?@[]^_{|}~\"\n\n/**\n * Drops every excluded character. `String.replace` with a string pattern only\n * removes the first match, so the exclusion is done with a set instead.\n */\nconst removeExceptions = (str: string, exclude: string): string => {\n if (!exclude) return str\n\n const banned = new Set([...exclude])\n return [...str].filter(char => !banned.has(char)).join('')\n}\n\n/**\n * Picks `count` characters from `pool`. Throws when the caller asked for\n * guaranteed characters out of a pool that `exclude` emptied.\n */\nconst pickFrom = (pool: string, count: number, name: string): string => {\n if (count === 0) return ''\n\n if (pool.length === 0) {\n throw new Error(\n `generate-password-lite: \\`exclude\\` removed every ${name} character, but \\`minLength${name[0]!.toUpperCase()}${name.slice(1)}\\` is ${count}.`\n )\n }\n\n let picked = ''\n for (let i = 0; i < count; i++) {\n picked += pool.charAt(generateRandomNumbers(pool.length))\n }\n return picked\n}\n\nexport const generatePswd = (options: ResolvedOptions): string => {\n const {\n length,\n lowercase,\n uppercase,\n numbers,\n symbols,\n minLengthLowercase,\n minLengthUppercase,\n minLengthNumbers,\n minLengthSymbols,\n exclude,\n } = options\n\n const lowercaseChar = removeExceptions(LOWERCASE_CHARS, exclude)\n const uppercaseChar = removeExceptions(UPPERCASE_CHARS, exclude)\n const numberChar = removeExceptions(NUMBER_CHARS, exclude)\n const symbolChar = removeExceptions(SYMBOL_CHARS, exclude)\n\n // Characters that must appear, so that the password satisfies every\n // `minLength*` the caller asked for.\n const guaranteed =\n pickFrom(lowercaseChar, minLengthLowercase, 'lowercase') +\n pickFrom(uppercaseChar, minLengthUppercase, 'uppercase') +\n pickFrom(numberChar, minLengthNumbers, 'numbers') +\n pickFrom(symbolChar, minLengthSymbols, 'symbols')\n\n // Every character the enabled classes still allow after exclusions.\n const characterPool =\n (lowercase ? lowercaseChar : '') +\n (uppercase ? uppercaseChar : '') +\n (numbers ? numberChar : '') +\n (symbols ? symbolChar : '')\n\n const remaining = length - guaranteed.length\n\n if (remaining > 0 && characterPool.length === 0) {\n throw new Error(\n 'generate-password-lite: `exclude` removed every character of every enabled class. No valid characters to generate the password from.'\n )\n }\n\n let filler = ''\n for (let i = 0; i < remaining; i++) {\n filler += characterPool.charAt(generateRandomNumbers(characterPool.length))\n }\n\n // Shuffle the whole password, not just the guaranteed part. Shuffling only\n // the guaranteed characters would pin them to the leading positions and make\n // the layout of the password predictable.\n return shuffleString(guaranteed + filler)\n}\n", "import { ResolvedOptions } from '../types'\n\nconst assertCount = (value: number, name: string) => {\n if (!Number.isInteger(value) || value < 0) {\n throw new Error(\n `generate-password-lite: \\`${name}\\` must be a non-negative integer, received ${value}.`\n )\n }\n}\n\nexport const checkError = (options: ResolvedOptions) => {\n const {\n length,\n lowercase,\n uppercase,\n numbers,\n symbols,\n minLengthLowercase,\n minLengthUppercase,\n minLengthNumbers,\n minLengthSymbols,\n } = options\n\n if (!Number.isInteger(length) || length < 1) {\n throw new Error(\n `generate-password-lite: \\`length\\` must be a positive integer, received ${length}.`\n )\n }\n\n assertCount(minLengthLowercase, 'minLengthLowercase')\n assertCount(minLengthUppercase, 'minLengthUppercase')\n assertCount(minLengthNumbers, 'minLengthNumbers')\n assertCount(minLengthSymbols, 'minLengthSymbols')\n\n // Lowercase, uppercase, numbers and symbols have all been turned off, so\n // there is no character class left to build a password from.\n if (!lowercase && !uppercase && !numbers && !symbols) {\n throw new Error(\n 'generate-password-lite: `lowercase`, `uppercase`, `numbers` and `symbols` are all false. No valid characters to generate the password from.'\n )\n }\n\n // The guaranteed characters alone would already overflow the password.\n const minimumTotal =\n minLengthLowercase + minLengthUppercase + minLengthNumbers + minLengthSymbols\n\n if (minimumTotal > length) {\n throw new Error(\n `generate-password-lite: the sum of the minimum character counts (${minimumTotal}) is greater than \\`length\\` (${length}).`\n )\n }\n}\n", "import { GenerateOptions, ResolvedOptions } from '../types'\n\nconst withDefault = <T>(value: T | undefined, fallback: T): T =>\n typeof value === 'undefined' ? fallback : value\n\n/**\n * Fills in every unset option. Returns a new object so that the caller's\n * options are never mutated.\n */\nexport const processOption = (options: GenerateOptions): ResolvedOptions => {\n const lowercase = withDefault(options.lowercase, true)\n const uppercase = withDefault(options.uppercase, true)\n const numbers = withDefault(options.numbers, true)\n const symbols = withDefault(options.symbols, false)\n\n // A disabled character class can never contribute a minimum, regardless of\n // what the caller passed in.\n return {\n length: withDefault(options.length, 10),\n lowercase,\n uppercase,\n numbers,\n symbols,\n exclude: withDefault(options.exclude, ''),\n minLengthLowercase: lowercase\n ? withDefault(options.minLengthLowercase, 1)\n : 0,\n minLengthUppercase: uppercase\n ? withDefault(options.minLengthUppercase, 1)\n : 0,\n minLengthNumbers: numbers ? withDefault(options.minLengthNumbers, 1) : 0,\n minLengthSymbols: symbols ? withDefault(options.minLengthSymbols, 1) : 0,\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* js-generate-password v1.1.0
|
|
3
|
+
* Tiny, dependency-free, cryptographically secure password generator for JavaScript and TypeScript projects.
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
export interface GenerateOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Length of the generated password.
|
|
9
|
+
* @default 10
|
|
10
|
+
*/
|
|
11
|
+
length?: number;
|
|
12
|
+
/**
|
|
13
|
+
* Should the password include lowercase characters.
|
|
14
|
+
* @default true
|
|
15
|
+
*/
|
|
16
|
+
lowercase?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Should the password include uppercase characters.
|
|
19
|
+
* @default true
|
|
20
|
+
*/
|
|
21
|
+
uppercase?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Should the password include numbers.
|
|
24
|
+
* @default true
|
|
25
|
+
*/
|
|
26
|
+
numbers?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Should the password include symbol characters.
|
|
29
|
+
* @default false
|
|
30
|
+
*/
|
|
31
|
+
symbols?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Characters to exclude from the password.
|
|
34
|
+
* @default ""
|
|
35
|
+
*/
|
|
36
|
+
exclude?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Minimum number of lowercase characters. Forced to 0 when `lowercase` is false.
|
|
39
|
+
* @default 1 when `lowercase` is true, otherwise 0
|
|
40
|
+
*/
|
|
41
|
+
minLengthLowercase?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Minimum number of uppercase characters. Forced to 0 when `uppercase` is false.
|
|
44
|
+
* @default 1 when `uppercase` is true, otherwise 0
|
|
45
|
+
*/
|
|
46
|
+
minLengthUppercase?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Minimum number of numeric characters. Forced to 0 when `numbers` is false.
|
|
49
|
+
* @default 1 when `numbers` is true, otherwise 0
|
|
50
|
+
*/
|
|
51
|
+
minLengthNumbers?: number;
|
|
52
|
+
/**
|
|
53
|
+
* Minimum number of symbol characters. Forced to 0 when `symbols` is false.
|
|
54
|
+
* @default 1 when `symbols` is true, otherwise 0
|
|
55
|
+
*/
|
|
56
|
+
minLengthSymbols?: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Generates a random password using a cryptographically secure random source.
|
|
60
|
+
*
|
|
61
|
+
* @param options - Optional overrides. Every unset option falls back to its
|
|
62
|
+
* documented default.
|
|
63
|
+
* @returns The generated password.
|
|
64
|
+
*/
|
|
65
|
+
declare function GeneratePassword(options?: GenerateOptions): string;
|
|
66
|
+
export { GeneratePassword, type GenerateOptions };
|
|
67
|
+
export default GeneratePassword;
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* js-generate-password v1.1.0
|
|
3
|
+
* Tiny, dependency-free, cryptographically secure password generator for JavaScript and TypeScript projects.
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
export interface GenerateOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Length of the generated password.
|
|
9
|
+
* @default 10
|
|
10
|
+
*/
|
|
11
|
+
length?: number;
|
|
12
|
+
/**
|
|
13
|
+
* Should the password include lowercase characters.
|
|
14
|
+
* @default true
|
|
15
|
+
*/
|
|
16
|
+
lowercase?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Should the password include uppercase characters.
|
|
19
|
+
* @default true
|
|
20
|
+
*/
|
|
21
|
+
uppercase?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Should the password include numbers.
|
|
24
|
+
* @default true
|
|
25
|
+
*/
|
|
26
|
+
numbers?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Should the password include symbol characters.
|
|
29
|
+
* @default false
|
|
30
|
+
*/
|
|
31
|
+
symbols?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Characters to exclude from the password.
|
|
34
|
+
* @default ""
|
|
35
|
+
*/
|
|
36
|
+
exclude?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Minimum number of lowercase characters. Forced to 0 when `lowercase` is false.
|
|
39
|
+
* @default 1 when `lowercase` is true, otherwise 0
|
|
40
|
+
*/
|
|
41
|
+
minLengthLowercase?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Minimum number of uppercase characters. Forced to 0 when `uppercase` is false.
|
|
44
|
+
* @default 1 when `uppercase` is true, otherwise 0
|
|
45
|
+
*/
|
|
46
|
+
minLengthUppercase?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Minimum number of numeric characters. Forced to 0 when `numbers` is false.
|
|
49
|
+
* @default 1 when `numbers` is true, otherwise 0
|
|
50
|
+
*/
|
|
51
|
+
minLengthNumbers?: number;
|
|
52
|
+
/**
|
|
53
|
+
* Minimum number of symbol characters. Forced to 0 when `symbols` is false.
|
|
54
|
+
* @default 1 when `symbols` is true, otherwise 0
|
|
55
|
+
*/
|
|
56
|
+
minLengthSymbols?: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Generates a random password using a cryptographically secure random source.
|
|
60
|
+
*
|
|
61
|
+
* @param options - Optional overrides. Every unset option falls back to its
|
|
62
|
+
* documented default.
|
|
63
|
+
* @returns The generated password.
|
|
64
|
+
*/
|
|
65
|
+
declare function GeneratePassword(options?: GenerateOptions): string;
|
|
66
|
+
export { GeneratePassword, type GenerateOptions };
|
|
67
|
+
export default GeneratePassword;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,67 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* js-generate-password v1.1.0
|
|
3
|
+
* Tiny, dependency-free, cryptographically secure password generator for JavaScript and TypeScript projects.
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
export interface GenerateOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Length of the generated password.
|
|
9
|
+
* @default 10
|
|
10
|
+
*/
|
|
11
|
+
length?: number;
|
|
12
|
+
/**
|
|
13
|
+
* Should the password include lowercase characters.
|
|
14
|
+
* @default true
|
|
15
|
+
*/
|
|
16
|
+
lowercase?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Should the password include uppercase characters.
|
|
19
|
+
* @default true
|
|
20
|
+
*/
|
|
21
|
+
uppercase?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Should the password include numbers.
|
|
24
|
+
* @default true
|
|
25
|
+
*/
|
|
26
|
+
numbers?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Should the password include symbol characters.
|
|
29
|
+
* @default false
|
|
30
|
+
*/
|
|
31
|
+
symbols?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Characters to exclude from the password.
|
|
34
|
+
* @default ""
|
|
35
|
+
*/
|
|
36
|
+
exclude?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Minimum number of lowercase characters. Forced to 0 when `lowercase` is false.
|
|
39
|
+
* @default 1 when `lowercase` is true, otherwise 0
|
|
40
|
+
*/
|
|
41
|
+
minLengthLowercase?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Minimum number of uppercase characters. Forced to 0 when `uppercase` is false.
|
|
44
|
+
* @default 1 when `uppercase` is true, otherwise 0
|
|
45
|
+
*/
|
|
46
|
+
minLengthUppercase?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Minimum number of numeric characters. Forced to 0 when `numbers` is false.
|
|
49
|
+
* @default 1 when `numbers` is true, otherwise 0
|
|
50
|
+
*/
|
|
51
|
+
minLengthNumbers?: number;
|
|
52
|
+
/**
|
|
53
|
+
* Minimum number of symbol characters. Forced to 0 when `symbols` is false.
|
|
54
|
+
* @default 1 when `symbols` is true, otherwise 0
|
|
55
|
+
*/
|
|
56
|
+
minLengthSymbols?: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Generates a random password using a cryptographically secure random source.
|
|
60
|
+
*
|
|
61
|
+
* @param options - Optional overrides. Every unset option falls back to its
|
|
62
|
+
* documented default.
|
|
63
|
+
* @returns The generated password.
|
|
64
|
+
*/
|
|
2
65
|
declare function GeneratePassword(options?: GenerateOptions): string;
|
|
3
66
|
export { GeneratePassword, type GenerateOptions };
|
|
67
|
+
export default GeneratePassword;
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* js-generate-password v1.1.0
|
|
3
|
+
* Tiny, dependency-free, cryptographically secure password generator for JavaScript and TypeScript projects.
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// src/lib/generate-random-number.ts
|
|
8
|
+
var UINT32_RANGE = 4294967296;
|
|
9
|
+
var getWebCrypto = () => {
|
|
10
|
+
const webCrypto = globalThis.crypto;
|
|
11
|
+
if (!webCrypto || typeof webCrypto.getRandomValues !== "function") {
|
|
12
|
+
throw new Error(
|
|
13
|
+
"js-generate-password: no Web Crypto implementation found. A secure random source is required to generate passwords. Use Node.js 18+, a modern browser, or polyfill `globalThis.crypto`."
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
return webCrypto;
|
|
17
|
+
};
|
|
18
|
+
var generateRandomNumbers = (upperLimit) => {
|
|
19
|
+
if (!Number.isInteger(upperLimit) || upperLimit <= 0) {
|
|
20
|
+
throw new RangeError(
|
|
21
|
+
`js-generate-password: upperLimit must be a positive integer, received ${upperLimit}.`
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
const webCrypto = getWebCrypto();
|
|
25
|
+
const buffer = new Uint32Array(1);
|
|
26
|
+
const cutoff = Math.floor(UINT32_RANGE / upperLimit) * upperLimit;
|
|
27
|
+
let value;
|
|
28
|
+
do {
|
|
29
|
+
webCrypto.getRandomValues(buffer);
|
|
30
|
+
value = buffer[0];
|
|
31
|
+
} while (value >= cutoff);
|
|
32
|
+
return value % upperLimit;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// src/lib/shuffle-string.ts
|
|
36
|
+
var shuffleString = (str) => {
|
|
37
|
+
const chars = [...str];
|
|
38
|
+
for (let i = chars.length - 1; i > 0; i--) {
|
|
39
|
+
const j = generateRandomNumbers(i + 1);
|
|
40
|
+
const tmp = chars[i];
|
|
41
|
+
chars[i] = chars[j];
|
|
42
|
+
chars[j] = tmp;
|
|
43
|
+
}
|
|
44
|
+
return chars.join("");
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// src/lib/password-generator.ts
|
|
48
|
+
var LOWERCASE_CHARS = "abcdefghijklmnopqrstuvwxyz";
|
|
49
|
+
var UPPERCASE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
50
|
+
var NUMBER_CHARS = "0123456789";
|
|
51
|
+
var SYMBOL_CHARS = "!#$%&'()*+,-./:;<=>?@[]^_{|}~";
|
|
52
|
+
var removeExceptions = (str, exclude) => {
|
|
53
|
+
if (!exclude) return str;
|
|
54
|
+
const banned = /* @__PURE__ */ new Set([...exclude]);
|
|
55
|
+
return [...str].filter((char) => !banned.has(char)).join("");
|
|
56
|
+
};
|
|
57
|
+
var pickFrom = (pool, count, name) => {
|
|
58
|
+
if (count === 0) return "";
|
|
59
|
+
if (pool.length === 0) {
|
|
60
|
+
throw new Error(
|
|
61
|
+
`js-generate-password: \`exclude\` removed every ${name} character, but \`minLength${name[0].toUpperCase()}${name.slice(1)}\` is ${count}.`
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
let picked = "";
|
|
65
|
+
for (let i = 0; i < count; i++) {
|
|
66
|
+
picked += pool.charAt(generateRandomNumbers(pool.length));
|
|
67
|
+
}
|
|
68
|
+
return picked;
|
|
69
|
+
};
|
|
70
|
+
var generatePswd = (options) => {
|
|
71
|
+
const {
|
|
72
|
+
length,
|
|
73
|
+
lowercase,
|
|
74
|
+
uppercase,
|
|
75
|
+
numbers,
|
|
76
|
+
symbols,
|
|
77
|
+
minLengthLowercase,
|
|
78
|
+
minLengthUppercase,
|
|
79
|
+
minLengthNumbers,
|
|
80
|
+
minLengthSymbols,
|
|
81
|
+
exclude
|
|
82
|
+
} = options;
|
|
83
|
+
const lowercaseChar = removeExceptions(LOWERCASE_CHARS, exclude);
|
|
84
|
+
const uppercaseChar = removeExceptions(UPPERCASE_CHARS, exclude);
|
|
85
|
+
const numberChar = removeExceptions(NUMBER_CHARS, exclude);
|
|
86
|
+
const symbolChar = removeExceptions(SYMBOL_CHARS, exclude);
|
|
87
|
+
const guaranteed = pickFrom(lowercaseChar, minLengthLowercase, "lowercase") + pickFrom(uppercaseChar, minLengthUppercase, "uppercase") + pickFrom(numberChar, minLengthNumbers, "numbers") + pickFrom(symbolChar, minLengthSymbols, "symbols");
|
|
88
|
+
const characterPool = (lowercase ? lowercaseChar : "") + (uppercase ? uppercaseChar : "") + (numbers ? numberChar : "") + (symbols ? symbolChar : "");
|
|
89
|
+
const remaining = length - guaranteed.length;
|
|
90
|
+
if (remaining > 0 && characterPool.length === 0) {
|
|
91
|
+
throw new Error(
|
|
92
|
+
"js-generate-password: `exclude` removed every character of every enabled class. No valid characters to generate the password from."
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
let filler = "";
|
|
96
|
+
for (let i = 0; i < remaining; i++) {
|
|
97
|
+
filler += characterPool.charAt(generateRandomNumbers(characterPool.length));
|
|
98
|
+
}
|
|
99
|
+
return shuffleString(guaranteed + filler);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// src/lib/check-options-error.ts
|
|
103
|
+
var assertCount = (value, name) => {
|
|
104
|
+
if (!Number.isInteger(value) || value < 0) {
|
|
105
|
+
throw new Error(
|
|
106
|
+
`js-generate-password: \`${name}\` must be a non-negative integer, received ${value}.`
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
var checkError = (options) => {
|
|
111
|
+
const {
|
|
112
|
+
length,
|
|
113
|
+
lowercase,
|
|
114
|
+
uppercase,
|
|
115
|
+
numbers,
|
|
116
|
+
symbols,
|
|
117
|
+
minLengthLowercase,
|
|
118
|
+
minLengthUppercase,
|
|
119
|
+
minLengthNumbers,
|
|
120
|
+
minLengthSymbols
|
|
121
|
+
} = options;
|
|
122
|
+
if (!Number.isInteger(length) || length < 1) {
|
|
123
|
+
throw new Error(
|
|
124
|
+
`js-generate-password: \`length\` must be a positive integer, received ${length}.`
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
assertCount(minLengthLowercase, "minLengthLowercase");
|
|
128
|
+
assertCount(minLengthUppercase, "minLengthUppercase");
|
|
129
|
+
assertCount(minLengthNumbers, "minLengthNumbers");
|
|
130
|
+
assertCount(minLengthSymbols, "minLengthSymbols");
|
|
131
|
+
if (!lowercase && !uppercase && !numbers && !symbols) {
|
|
132
|
+
throw new Error(
|
|
133
|
+
"js-generate-password: `lowercase`, `uppercase`, `numbers` and `symbols` are all false. No valid characters to generate the password from."
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
const minimumTotal = minLengthLowercase + minLengthUppercase + minLengthNumbers + minLengthSymbols;
|
|
137
|
+
if (minimumTotal > length) {
|
|
138
|
+
throw new Error(
|
|
139
|
+
`js-generate-password: the sum of the minimum character counts (${minimumTotal}) is greater than \`length\` (${length}).`
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// src/lib/process-options.ts
|
|
145
|
+
var withDefault = (value, fallback) => typeof value === "undefined" ? fallback : value;
|
|
146
|
+
var processOption = (options) => {
|
|
147
|
+
const lowercase = withDefault(options.lowercase, true);
|
|
148
|
+
const uppercase = withDefault(options.uppercase, true);
|
|
149
|
+
const numbers = withDefault(options.numbers, true);
|
|
150
|
+
const symbols = withDefault(options.symbols, false);
|
|
151
|
+
return {
|
|
152
|
+
length: withDefault(options.length, 10),
|
|
153
|
+
lowercase,
|
|
154
|
+
uppercase,
|
|
155
|
+
numbers,
|
|
156
|
+
symbols,
|
|
157
|
+
exclude: withDefault(options.exclude, ""),
|
|
158
|
+
minLengthLowercase: lowercase ? withDefault(options.minLengthLowercase, 1) : 0,
|
|
159
|
+
minLengthUppercase: uppercase ? withDefault(options.minLengthUppercase, 1) : 0,
|
|
160
|
+
minLengthNumbers: numbers ? withDefault(options.minLengthNumbers, 1) : 0,
|
|
161
|
+
minLengthSymbols: symbols ? withDefault(options.minLengthSymbols, 1) : 0
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
// src/index.ts
|
|
166
|
+
function GeneratePassword(options = {}) {
|
|
167
|
+
const resolved = processOption(options);
|
|
168
|
+
checkError(resolved);
|
|
169
|
+
return generatePswd(resolved);
|
|
170
|
+
}
|
|
171
|
+
var index_default = GeneratePassword;
|
|
172
|
+
export {
|
|
173
|
+
GeneratePassword,
|
|
174
|
+
index_default as default
|
|
175
|
+
};
|
|
176
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/lib/generate-random-number.ts", "../src/lib/shuffle-string.ts", "../src/lib/password-generator.ts", "../src/lib/check-options-error.ts", "../src/lib/process-options.ts", "../src/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Number of distinct values a Uint32 can hold.\n */\nconst UINT32_RANGE = 0x100000000\n\nconst getWebCrypto = (): Crypto => {\n const webCrypto = globalThis.crypto\n\n if (!webCrypto || typeof webCrypto.getRandomValues !== 'function') {\n throw new Error(\n 'generate-password-lite: no Web Crypto implementation found. ' +\n 'A secure random source is required to generate passwords. ' +\n 'Use Node.js 18+, a modern browser, or polyfill `globalThis.crypto`.'\n )\n }\n\n return webCrypto\n}\n\n/**\n * Returns a cryptographically secure integer in the range [0, upperLimit).\n *\n * Uses rejection sampling so that every value is equally likely. Taking a\n * plain `random % upperLimit` would bias the low end of the range whenever\n * `upperLimit` is not a power of two.\n */\nexport const generateRandomNumbers = (upperLimit: number): number => {\n if (!Number.isInteger(upperLimit) || upperLimit <= 0) {\n throw new RangeError(\n `generate-password-lite: upperLimit must be a positive integer, received ${upperLimit}.`\n )\n }\n\n const webCrypto = getWebCrypto()\n const buffer = new Uint32Array(1)\n\n // Largest multiple of upperLimit that fits in the Uint32 range. Draws at or\n // above this cutoff are discarded rather than folded back into the range.\n const cutoff = Math.floor(UINT32_RANGE / upperLimit) * upperLimit\n\n let value: number\n do {\n webCrypto.getRandomValues(buffer)\n value = buffer[0]!\n } while (value >= cutoff)\n\n return value % upperLimit\n}\n", "import { generateRandomNumbers } from './generate-random-number'\n\n/**\n * Fisher-Yates shuffle backed by the same cryptographically secure source\n * used to pick the characters themselves.\n *\n * Spreads across code points rather than UTF-16 units so that a surrogate\n * pair supplied through `exclude` handling is never split in half.\n */\nexport const shuffleString = (str: string): string => {\n const chars = [...str]\n\n for (let i = chars.length - 1; i > 0; i--) {\n const j = generateRandomNumbers(i + 1)\n const tmp = chars[i]!\n chars[i] = chars[j]!\n chars[j] = tmp\n }\n\n return chars.join('')\n}\n", "import { generateRandomNumbers } from './generate-random-number'\nimport { shuffleString } from './shuffle-string'\nimport { ResolvedOptions } from '../types'\n\nconst LOWERCASE_CHARS = 'abcdefghijklmnopqrstuvwxyz'\nconst UPPERCASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'\nconst NUMBER_CHARS = '0123456789'\nconst SYMBOL_CHARS = \"!#$%&'()*+,-./:;<=>?@[]^_{|}~\"\n\n/**\n * Drops every excluded character. `String.replace` with a string pattern only\n * removes the first match, so the exclusion is done with a set instead.\n */\nconst removeExceptions = (str: string, exclude: string): string => {\n if (!exclude) return str\n\n const banned = new Set([...exclude])\n return [...str].filter(char => !banned.has(char)).join('')\n}\n\n/**\n * Picks `count` characters from `pool`. Throws when the caller asked for\n * guaranteed characters out of a pool that `exclude` emptied.\n */\nconst pickFrom = (pool: string, count: number, name: string): string => {\n if (count === 0) return ''\n\n if (pool.length === 0) {\n throw new Error(\n `generate-password-lite: \\`exclude\\` removed every ${name} character, but \\`minLength${name[0]!.toUpperCase()}${name.slice(1)}\\` is ${count}.`\n )\n }\n\n let picked = ''\n for (let i = 0; i < count; i++) {\n picked += pool.charAt(generateRandomNumbers(pool.length))\n }\n return picked\n}\n\nexport const generatePswd = (options: ResolvedOptions): string => {\n const {\n length,\n lowercase,\n uppercase,\n numbers,\n symbols,\n minLengthLowercase,\n minLengthUppercase,\n minLengthNumbers,\n minLengthSymbols,\n exclude,\n } = options\n\n const lowercaseChar = removeExceptions(LOWERCASE_CHARS, exclude)\n const uppercaseChar = removeExceptions(UPPERCASE_CHARS, exclude)\n const numberChar = removeExceptions(NUMBER_CHARS, exclude)\n const symbolChar = removeExceptions(SYMBOL_CHARS, exclude)\n\n // Characters that must appear, so that the password satisfies every\n // `minLength*` the caller asked for.\n const guaranteed =\n pickFrom(lowercaseChar, minLengthLowercase, 'lowercase') +\n pickFrom(uppercaseChar, minLengthUppercase, 'uppercase') +\n pickFrom(numberChar, minLengthNumbers, 'numbers') +\n pickFrom(symbolChar, minLengthSymbols, 'symbols')\n\n // Every character the enabled classes still allow after exclusions.\n const characterPool =\n (lowercase ? lowercaseChar : '') +\n (uppercase ? uppercaseChar : '') +\n (numbers ? numberChar : '') +\n (symbols ? symbolChar : '')\n\n const remaining = length - guaranteed.length\n\n if (remaining > 0 && characterPool.length === 0) {\n throw new Error(\n 'generate-password-lite: `exclude` removed every character of every enabled class. No valid characters to generate the password from.'\n )\n }\n\n let filler = ''\n for (let i = 0; i < remaining; i++) {\n filler += characterPool.charAt(generateRandomNumbers(characterPool.length))\n }\n\n // Shuffle the whole password, not just the guaranteed part. Shuffling only\n // the guaranteed characters would pin them to the leading positions and make\n // the layout of the password predictable.\n return shuffleString(guaranteed + filler)\n}\n", "import { ResolvedOptions } from '../types'\n\nconst assertCount = (value: number, name: string) => {\n if (!Number.isInteger(value) || value < 0) {\n throw new Error(\n `generate-password-lite: \\`${name}\\` must be a non-negative integer, received ${value}.`\n )\n }\n}\n\nexport const checkError = (options: ResolvedOptions) => {\n const {\n length,\n lowercase,\n uppercase,\n numbers,\n symbols,\n minLengthLowercase,\n minLengthUppercase,\n minLengthNumbers,\n minLengthSymbols,\n } = options\n\n if (!Number.isInteger(length) || length < 1) {\n throw new Error(\n `generate-password-lite: \\`length\\` must be a positive integer, received ${length}.`\n )\n }\n\n assertCount(minLengthLowercase, 'minLengthLowercase')\n assertCount(minLengthUppercase, 'minLengthUppercase')\n assertCount(minLengthNumbers, 'minLengthNumbers')\n assertCount(minLengthSymbols, 'minLengthSymbols')\n\n // Lowercase, uppercase, numbers and symbols have all been turned off, so\n // there is no character class left to build a password from.\n if (!lowercase && !uppercase && !numbers && !symbols) {\n throw new Error(\n 'generate-password-lite: `lowercase`, `uppercase`, `numbers` and `symbols` are all false. No valid characters to generate the password from.'\n )\n }\n\n // The guaranteed characters alone would already overflow the password.\n const minimumTotal =\n minLengthLowercase + minLengthUppercase + minLengthNumbers + minLengthSymbols\n\n if (minimumTotal > length) {\n throw new Error(\n `generate-password-lite: the sum of the minimum character counts (${minimumTotal}) is greater than \\`length\\` (${length}).`\n )\n }\n}\n", "import { GenerateOptions, ResolvedOptions } from '../types'\n\nconst withDefault = <T>(value: T | undefined, fallback: T): T =>\n typeof value === 'undefined' ? fallback : value\n\n/**\n * Fills in every unset option. Returns a new object so that the caller's\n * options are never mutated.\n */\nexport const processOption = (options: GenerateOptions): ResolvedOptions => {\n const lowercase = withDefault(options.lowercase, true)\n const uppercase = withDefault(options.uppercase, true)\n const numbers = withDefault(options.numbers, true)\n const symbols = withDefault(options.symbols, false)\n\n // A disabled character class can never contribute a minimum, regardless of\n // what the caller passed in.\n return {\n length: withDefault(options.length, 10),\n lowercase,\n uppercase,\n numbers,\n symbols,\n exclude: withDefault(options.exclude, ''),\n minLengthLowercase: lowercase\n ? withDefault(options.minLengthLowercase, 1)\n : 0,\n minLengthUppercase: uppercase\n ? withDefault(options.minLengthUppercase, 1)\n : 0,\n minLengthNumbers: numbers ? withDefault(options.minLengthNumbers, 1) : 0,\n minLengthSymbols: symbols ? withDefault(options.minLengthSymbols, 1) : 0,\n }\n}\n", "import { generatePswd } from './lib/password-generator'\nimport { checkError } from './lib/check-options-error'\nimport { processOption } from './lib/process-options'\nimport { GenerateOptions } from './types'\n\n/**\n * Generates a random password using a cryptographically secure random source.\n *\n * @param options - Optional overrides. Every unset option falls back to its\n * documented default.\n * @returns The generated password.\n */\nfunction GeneratePassword(options: GenerateOptions = {}): string {\n const resolved = processOption(options)\n\n checkError(resolved)\n\n return generatePswd(resolved)\n}\n\nexport { GeneratePassword, type GenerateOptions }\nexport default GeneratePassword\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|