1import { UnavailabilityError } from '@unimodules/core'; 2import { toByteArray } from 'base64-js'; 3 4import ExpoRandom from './ExpoRandom'; 5 6function assertByteCount(value: any, methodName: string): void { 7 if ( 8 typeof value !== 'number' || 9 isNaN(value) || 10 Math.floor(value) < 0 || 11 Math.floor(value) > 1024 12 ) { 13 throw new TypeError( 14 `expo-random: ${methodName}(${value}) expected a valid number from range 0...1024` 15 ); 16 } 17} 18 19// @needsAudit 20/** 21 * Generates completely random bytes using native implementations. The `byteCount` property 22 * is a `number` indicating the number of bytes to generate in the form of a `Uint8Array`. 23 * @param byteCount - A number within the range from `0` to `1024`. Anything else will throw a `TypeError`. 24 * @return An array of random bytes with the same length as the `byteCount`. 25 */ 26export function getRandomBytes(byteCount: number): Uint8Array { 27 assertByteCount(byteCount, 'getRandomBytes'); 28 const validByteCount = Math.floor(byteCount); 29 if (ExpoRandom.getRandomBytes) { 30 return ExpoRandom.getRandomBytes(validByteCount); 31 } else if (ExpoRandom.getRandomBase64String) { 32 const base64 = ExpoRandom.getRandomBase64String(validByteCount); 33 return toByteArray(base64); 34 } else { 35 throw new UnavailabilityError('expo-random', 'getRandomBytes'); 36 } 37} 38 39// @needsAudit 40/** 41 * Generates completely random bytes using native implementations. The `byteCount` property 42 * is a `number` indicating the number of bytes to generate in the form of a `Uint8Array`. 43 * @param byteCount - A number within the range from `0` to `1024`. Anything else will throw a `TypeError`. 44 * @return A promise that fulfills with an array of random bytes with the same length as the `byteCount`. 45 */ 46export async function getRandomBytesAsync(byteCount: number): Promise<Uint8Array> { 47 assertByteCount(byteCount, 'getRandomBytesAsync'); 48 const validByteCount = Math.floor(byteCount); 49 if (ExpoRandom.getRandomBytesAsync) { 50 return await ExpoRandom.getRandomBytesAsync(validByteCount); 51 } else if (ExpoRandom.getRandomBase64StringAsync) { 52 const base64 = await ExpoRandom.getRandomBase64StringAsync(validByteCount); 53 return toByteArray(base64); 54 } else { 55 throw new UnavailabilityError('expo-random', 'getRandomBytesAsync'); 56 } 57} 58