const { common } = require('@squeep/api-dingus');
-const { randomBytes } = require('crypto');
-const { promisify } = require('util');
+const { randomBytes } = require('node:crypto');
+const { promisify } = require('node:util');
const randomBytesAsync = promisify(randomBytes);
/**
* Limit length of string to keep logs sane
- * @param {String} str
- * @param {Number} len
- * @returns {String}
+ * @param {string} str str
+ * @param {number} len len
+ * @returns {string} str
*/
const logTruncate = (str, len) => {
if (typeof str !== 'string' || str.toString().length <= len) {
/**
* Turn a snake into a camel.
- * @param {String} snakeCase
- * @param {String|RegExp} delimiter
- * @returns {String}
+ * @param {string} snakeCase snake case
+ * @param {string | RegExp} delimiter delimiter
+ * @returns {string} camel case
*/
const camelfy = (snakeCase, delimiter = '_') => {
if (!snakeCase || typeof snakeCase.split !== 'function') {
/**
* Return an array containing x if x is not an array.
- * @param {*} x
+ * @param {*} x x
+ * @returns {any[]} x[]
*/
const ensureArray = (x) => {
if (x === undefined) {
/**
* Recursively freeze an object.
- * @param {Object} o
- * @returns {Object}
+ * @param {object} o obj
+ * @returns {object} frozen obj
*/
const freezeDeep = (o) => {
Object.freeze(o);
Object.getOwnPropertyNames(o).forEach((prop) => {
- if (Object.hasOwnProperty.call(o, prop)
+ if (Object.hasOwn(o, prop)
&& ['object', 'function'].includes(typeof o[prop]) // eslint-disable-line security/detect-object-injection
&& !Object.isFrozen(o[prop])) { // eslint-disable-line security/detect-object-injection
return freezeDeep(o[prop]); // eslint-disable-line security/detect-object-injection
};
-/** Oauth2.1 §3.2.3.1
+/**
+ * Oauth2.1 §3.2.3.1
* %x20-21 / %x23-5B / %x5D-7E
- * @param {String} char
+ * ' '-'!' / '#'-'[' / ']'-'~'
+ * not allowed: control characters, '"', '\'
+ * @param {string} char character
+ * @returns {boolean} is valid
*/
const validErrorChar = (char) => {
const value = char.charCodeAt(0);
/**
* Determine if an OAuth error message is valid.
- * @param {String} error
- * @returns {Boolean}
+ * @param {string} error error
+ * @returns {boolean} is valid
*/
const validError = (error) => {
return error && error.split('').filter((c) => !validErrorChar(c)).length === 0 || false;
/**
* OAuth2.1 §3.2.2.1
* scope-token = 1*( %x21 / %x23-5B / %x5D-7E )
- * @param {String} char
+ * @param {string} char char
+ * @returns {boolean} is valid
*/
const validScopeChar = (char) => {
const value = char.charCodeAt(0);
/**
* Determine if a scope has a valid name.
- * @param {String} scope
- * @returns {Boolean}
+ * @param {string} scope scope
+ * @returns {boolean} is valid
*/
const validScope = (scope) => {
return scope && scope.split('').filter((c) => !validScopeChar(c)).length === 0 || false;
/**
*
- * @param {Number} bytes
+ * @param {number} bytes bytes
+ * @returns {string} base64 random string
*/
const newSecret = async (bytes = 64) => {
return (await randomBytesAsync(bytes * 3 / 4)).toString('base64');
/**
* Convert a Date object to epoch seconds.
- * @param {Date=} date
- * @returns {Number}
+ * @param {Date=} date date
+ * @returns {number} epoch
*/
const dateToEpoch = (date) => {
const dateMs = date ? date.getTime() : Date.now();
const omit = (o, props) => {
- return Object.fromEntries(Object.entries(o).filter(([k]) => !props.includes(k)))
+ return Object.fromEntries(Object.entries(o).filter(([k]) => !props.includes(k)));
};
+/**
+ * @typedef {object} ConsoleLike
+ * @property {Function} debug log debug
+ */
+
/**
* Log Mystery Box statistics events.
- * @param {Console} logger
- * @param {String} scope
+ * @param {ConsoleLike} logger logger instance
+ * @param {string} scope scope
+ * @returns {Function} stat logger
*/
const mysteryBoxLogger = (logger, scope) => {
return (s) => {
};
+const nop = () => { /**/ };
+
module.exports = {
...common,
camelfy,
randomBytesAsync,
validScope,
validError,
+ nop,
};