@handy-common-utils/misc-utils
Version:
Miscellaneous utilities
182 lines • 9 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.urlSafe = urlSafe;
exports.base64FromUInt32 = base64FromUInt32;
exports.shortBase64FromUInt32 = shortBase64FromUInt32;
exports.base64UrlFromUInt32 = base64UrlFromUInt32;
exports.shortBase64UrlFromUInt32 = shortBase64UrlFromUInt32;
exports.generateRandomString = generateRandomString;
exports.generateRandomStringQuickly = generateRandomStringQuickly;
exports.escapeForRegExp = escapeForRegExp;
exports.escapeForRegExpReplacement = escapeForRegExpReplacement;
/* eslint-disable unicorn/prefer-node-protocol, unicorn/prefer-string-replace-all, unicorn/prefer-string-raw */
const crypto = __importStar(require("crypto"));
/**
* Make a "normal" (BASE64) string URL/path safe.
* @param base64Input A (BASE64) string which could be null or undefined.
* @param replacements A string containing replacement characters for "/", "+", and "=".
* If omitted, default value of '_-=' would be used.
* @returns URL/path safe version of the (BASE64) input string, or the original input if it is null or undefined.
*/
function urlSafe(base64Input, replacements = '_-=') {
if (base64Input == null) {
return base64Input;
}
return base64Input.replace(/\//g, replacements.charAt(0))
.replace(/\+/g, replacements.charAt(1))
.replace(/=/g, replacements.charAt(2));
}
/**
* Encode an unsigned 32-bit integer into BASE64 string.
* @param ui32 A 32-bit integer number which could also be null or undefined.
* It must be a valid unsigned 32-bit integer. Behavior is undefined when the value is anything other than an unsigned 32-bit integer.
* If you don't care about loosing precision, you can convert a number by doing `n >>> 0` (See https://stackoverflow.com/questions/22335853/hack-to-convert-javascript-number-to-uint32)
* @returns BASE64 string representing the integer input, or the original input if it is null or undefined.
*/
function base64FromUInt32(ui32) {
if (ui32 == null) {
return ui32;
}
// This is the version works in Node.js but not browsers
// const buf = Buffer.allocUnsafe(4);
// buf.writeUInt32BE(ui32!, 0);
// return buf.toString('base64');
// This is the version works in both Node.js and browsers
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
view.setUint32(0, ui32, false); // 'false' specifies Big-Endian
const uint8Array = new Uint8Array(buffer);
let binaryString = '';
uint8Array.forEach(byte => {
// eslint-disable-next-line unicorn/prefer-code-point
binaryString += String.fromCharCode(byte);
});
return btoa(binaryString);
}
/**
* Encode an unsigned 32-bit integer into BASE64 string without trailing '='.
* @param ui32 A 32-bit integer number which could also be null or undefined.
* It must be a valid unsigned 32-bit integer. Behavior is undefined when the value is anything other than an unsigned 32-bit integer.
* If you don't care about loosing precision, you can convert a number by doing `n >>> 0` (See https://stackoverflow.com/questions/22335853/hack-to-convert-javascript-number-to-uint32)
* @returns BASE64 string without trailing '=' representing the integer input, or the original input if it is null or undefined.
*/
function shortBase64FromUInt32(ui32) {
if (ui32 == null) {
return ui32;
}
return base64FromUInt32(ui32).replace(/=+$/, '');
}
/**
* Encode an unsigned 32-bit integer into URL/path safe BASE64 string.
* @param ui32 A 32-bit integer number which could also be null or undefined.
* It must be a valid unsigned 32-bit integer. Behavior is undefined when the value is anything other than an unsigned 32-bit integer.
* If you don't care about loosing precision, you can convert a number by doing `n >>> 0` (See https://stackoverflow.com/questions/22335853/hack-to-convert-javascript-number-to-uint32)
* @param replacements A string containing replacement characters for "/", "+", and "=".
* If omitted, default value of '_-=' would be used.
* @returns URL/path safe BASE64 string representing the integer input, or the original input if it is null or undefined.
*/
function base64UrlFromUInt32(ui32, replacements = '_-=') {
return urlSafe(base64FromUInt32(ui32), replacements);
}
/**
* Encode an unsigned 32-bit integer into URL/path safe BASE64 string without trailing '='.
* @param ui32 A 32-bit integer number which could also be null or undefined.
* It must be a valid unsigned 32-bit integer. Behavior is undefined when the value is anything other than an unsigned 32-bit integer.
* If you don't care about loosing precision, you can convert a number by doing `n >>> 0` (See https://stackoverflow.com/questions/22335853/hack-to-convert-javascript-number-to-uint32)
* @param replacements A string containing replacement characters for "/" and "+".
* If omitted, default value of '_-' would be used.
* @returns URL/path safe BASE64 string without trailing '=' representing the integer input, or the original input if it is null or undefined.
*/
function shortBase64UrlFromUInt32(ui32, replacements = '_-') {
return urlSafe(shortBase64FromUInt32(ui32), replacements);
}
/**
* Generate a strong (using crypto.randomFillSync(...)) random string that is URL/path safe.
* In the generated string, approximately every 6 characters represent randomly generated 32 bits.
* For example, if you need 128 bits of randomness, you just need to generate a string containing 24 characters.
* @param len length of the string to be generated
* @returns the random string
*/
function generateRandomString(len) {
// 32 bits => 6 characters
const numbers = new Uint32Array(Math.ceil((len + 1) / 6));
crypto.randomFillSync(numbers);
const strings = [];
for (const i of numbers) {
strings.push(shortBase64UrlFromUInt32(i));
}
return strings.join('').slice(0, len);
}
/**
* Generate a weak (using Math.random()) random string that is URL/path safe.
* In the generated string, approximately every 6 characters represent randomly generated 32 bits.
* For example, if you need 128 bits of randomness, you just need to generate a string containing 24 characters.
* @param len length of the string to be generated
* @returns the random string
*/
function generateRandomStringQuickly(len) {
// 32 bits => 6 characters
const strings = [];
for (let i = 0; i < Math.ceil((len + 1) / 6); i++) {
strings.push(shortBase64UrlFromUInt32((Math.random() * 4294967295) >>> 0));
}
return strings.join('').slice(0, len);
}
/**
* Escape a string literal for using it inside of RegExp.
* (From: https://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex)
* @param text the string literal to be escaped
* @returns escaped string that can be used inside of RegExp, or an empty string if the input is null or undefined
*/
function escapeForRegExp(text) {
if (text == null) {
return '';
}
return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
/**
* Escape replacement string for using it inside of RegExp replacement parameter.
* (From: https://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex)
* @param text the replacement string to be escaped, or an empty string if the input is null or undefined
* @returns escaped replacement string that can be used inside of RegExp replacement parameter
*/
function escapeForRegExpReplacement(text) {
if (text == null) {
return '';
}
return text.replace(/\$/g, '$$$$');
}
//# sourceMappingURL=codec.js.map