}
});
return o;
-}
+};
+
+/**
+ * Return a new object duplicating `o`, without the properties specified.
+ * @param {Object} o
+ * @param {String[]} props
+ * @returns {Object}
+ */
+const omit = (o, props) => {
+ return Object.fromEntries(Object.entries(o).filter(([k]) => !props.includes(k)));
+};
+
+/**
+ * Helper to log mystery-box statistics.
+ * @param {ConsoleLike} logger
+ * @param {String} scope
+ * @returns {Function}
+ */
+const mysteryBoxLogger = (logger, scope) => {
+ return (s) => {
+ logger.debug(scope, `${s.packageName}@${s.packageVersion}:${s.method}`, omit(s, [
+ 'packageName',
+ 'packageVersion',
+ 'method',
+ ]));
+ };
+};
+
+/**
+ * Hide sensitive part of an Authorization header.
+ * @param {String} authHeader
+ * @returns {String}
+ */
+const obscureAuthorizationHeader = (authHeader) => {
+ if (!authHeader) {
+ return authHeader;
+ }
+ const space = authHeader.indexOf(' ');
+ // This blurs entire string if no space found, because -1.
+ return authHeader.slice(0, space + 1) + '*'.repeat(authHeader.length - (space + 1));
+};
module.exports = Object.assign(Object.create(common), {
freezeDeep,
+ mysteryBoxLogger,
+ obscureAuthorizationHeader,
+ omit,
});
\ No newline at end of file