ts-randomstring
Version:
A library used for generating random strings, written in TypeScript and based on Node.
188 lines (187 loc) • 8.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.RandomString = exports.generateRandomStringAsync = exports.generateRandomString = void 0;
const crypto_1 = require("crypto");
const characterSetHandler_1 = require("./characterSetHandler");
/**
* Generates and returns a random string.
* The optional random string options define the nature of the string to generated.
*
* This method instantiates a new `RandomString` class before executing `generate`.
* For multiple string generations, it is recommended to instantiate a `RandomString` instance yourself.
*
* @param options The random string options to parse and apply to string generation.
* Supported options:
* ```
* length: number (default=32)
* charSetType: CharacterSetType (default=CharacterSetType.Alphanumeric)
* capitalisation/capitalization: Capitalisation/Capitalization (default=Capitalisation.Mixed)
* ```
* @returns The randomly generated string.
*/
const generateRandomString = (options) => {
const randomString = new RandomString();
return randomString.generate(options);
};
exports.generateRandomString = generateRandomString;
/**
* Asynchronously generates a random string, executing the passed callback when generation is complete which contains the generated string.
* The optional random string options define the nature of the string to generated.
*
* This method instantiates a new `RandomString` class before executing `generateAsync`.
* For multiple string generations, it is recommended to instantiate a `RandomString` instance yourself.
*
* @param callback The callback (`error`, `generated`) to execute when generation is complete.
* @param options The random string options to parse and apply to string generation.
* Supported options:
* ```
* length: number (default=32)
* charSetType: CharacterSetType (default=CharacterSetType.Alphanumeric)
* capitalisation/capitalization: Capitalisation/Capitalization (default=Capitalisation.Mixed)
* ```
* @returns void.
*/
const generateRandomStringAsync = (callback, options) => {
const randomString = new RandomString();
randomString.generateAsync(callback, options);
};
exports.generateRandomStringAsync = generateRandomStringAsync;
/**
* The primary class for generating random strings.
*/
class RandomString {
/**
* Generates and returns a random string.
* The optional random string options define the nature of the string to generated.
*
* @param options The random string options to parse and apply to string generation.
* Supported options:
* ```
* length: number (default=32)
* charSetType: CharacterSetType (default=CharacterSetType.Alphanumeric)
* capitalisation/capitalization: Capitalisation/Capitalization (default=Capitalisation.Mixed)
* ```
* @returns The randomly generated string.
*/
generate(options) {
const [length, charSetType, capitalisation] = this.parseOptions(options);
const charSet = characterSetHandler_1.getCharacterSet(charSetType, capitalisation);
let generated = "";
while (generated.length < length) {
const maxByte = this.getMaxByte(charSet.length);
const buffer = this.getRandomBytesSafe(Math.ceil(length * 256 / maxByte));
if (buffer instanceof (Error)) {
return `getRandomBytesSafe internal error :: ${buffer}`;
}
else {
const state = {
generated,
charSet,
length,
maxByte
};
generated = this.generateString(buffer, state);
}
}
return generated;
}
/**
* Asynchronously generates a random string, executing the passed callback when generation is complete which contains the generated string.
* The optional random string options define the nature of the string to generated.
*
* @param callback The callback (`error`, `generated`) to execute when generation is complete.
* @param options The random string options to parse and apply to string generation.
* Supported options:
* ```
* length: number (default=32)
* charSetType: CharacterSetType (default=CharacterSetType.Alphanumeric)
* capitalisation/capitalization: Capitalisation/Capitalization (default=Capitalisation.Mixed)
* ```
* @returns void.
*/
generateAsync(callback, options) {
const [length, charSetType, capitalisation] = this.parseOptions(options);
const charSet = characterSetHandler_1.getCharacterSet(charSetType, capitalisation);
const state = {
generated: "",
charSet,
length,
maxByte: this.getMaxByte(charSet.length)
};
this.generateStringAsync(state, callback);
}
/**
* Parses the passed random string options, returning their values if specified or their default values if not.
*
* @param options The random string options to parse.
* @returns The parsed options values.
*/
parseOptions(options) {
var _a, _b, _c;
return [
(_a = options === null || options === void 0 ? void 0 : options.length) !== null && _a !== void 0 ? _a : 32,
(_b = options === null || options === void 0 ? void 0 : options.charSetType) !== null && _b !== void 0 ? _b : characterSetHandler_1.CharacterSetType.Alphanumeric,
(_c = options === null || options === void 0 ? void 0 : options.capitalisation) !== null && _c !== void 0 ? _c : characterSetHandler_1.Capitalisation.Mixed
];
}
/**
* Returns the maximum byte for a particular character set.
*
* @param length The length of the current character set (i.e., the unique characters in the set).
* @returns The maximum byte value.
*/
getMaxByte(length) {
return 256 - (256 % length);
}
/**
* Safely attempts to generate a buffer of randomly generated bytes.
*
* @param length The required buffer length of the randomly generated buffer.
* @returns The randomly generated buffer or an error if an error is caught.
*/
getRandomBytesSafe(length) {
try {
return crypto_1.randomBytes(length);
}
catch (error) {
return error;
}
}
/**
* Generates a random string.
* @param buffer The randomly generated buffer which is used as the base for random characters.
* @param state See {@link GeneratedStringState} for generated string state documentation.
* @returns The generated string.
*/
generateString(buffer, state) {
for (let i = 0; i < buffer.length && state.generated.length < state.length; i++) {
const randomByte = buffer.readUInt8(i);
if (randomByte < state.maxByte) {
state.generated += state.charSet.charAt(randomByte % state.charSet.length);
}
}
return state.generated;
}
/**
* Generates a random string asynchronously. That is, the passed callback is executed when generation completes
*
* @param state See {@link GeneratedStringState} for generated string state documentation.
* @param callback The callback (`error`, `generated`) executed when string generation is complete.
* @returns void.
*/
generateStringAsync(state, callback) {
crypto_1.randomBytes(length, (error, buffer) => {
if (error) {
callback(error, undefined);
}
const newGenerated = this.generateString(buffer, state);
if (newGenerated.length < length) {
this.generateStringAsync(state, callback);
}
else {
callback(undefined, newGenerated);
}
});
}
}
exports.RandomString = RandomString;