There are about million questions like this, but each and every answer I saw just uses Math.random() (and in the rare case where someone has managed to use crypto.getRandomValues(), it's incredibly biased), but I need something that's cryptographically secure. I'm looking especially something like Python's secrets.randbelow(). Even better if there's a counterpart to secrets.choice(). Is there anything like that available in the standard Javascript without jQuery or other insanely large and complex dependencies? I couldn't find anything from Mozilla's documentation either.
Or should I just implement it myself? Would something like the following work or is there something I have completely missed?
//Return a random int in the range [0, n).
function randbelow(n) {
  if (n < 1) {
    throw 'Upper bound must be positive.';
  }
  if (n === 1) {
    return 0;
  }
  const maxsize = 2 ** 32;
  if (n > maxsize) {
    throw 'Only unsigned 32-bit integers are supported.';
  }
  const rem = maxsize % n;
  const limit = maxsize - rem;
  let r;
  do {
    r = crypto.getRandomValues(new Uint32Array(1))[0];
  } while (r >= limit);
  return r % n;
}
// test
var arr = ['item1', 'item2', 'item3'];
console.log(arr[randbelow(arr.length)]);