import { type ScryptOptions } from 'node:crypto'; // export declare const MAX_UINT32: number; // export declare const MAX_UINT24: number; import { promisify } from 'node:util'; import { randomBytes, scrypt } from 'node:crypto'; import phc from '@phc/format'; /** * Validates a number to be within a given range. */ export class RangeValidator { // static validate(label: string, value: unknown, range: [number, number]): void; static validate(label: string, value: unknown, range: [number, number]): void { if (typeof value !== 'number' || !Number.isInteger(value)) { throw new TypeError(`The "${label}" option must be an integer`); } const [min, max] = range; if (value < min || value > max) { throw new TypeError(`The "${label}" option must be in the range (${min} <= ${label} <= ${max})`); } } } /** * Validates a value to be one of the allowed values */ export class EnumValidator { // static validate(label: string, value: unknown, allowedValues: any[]): void; static validate(label: string, value: unknown, allowedValues: any[]): void { if (!allowedValues.includes(value)) { throw new TypeError(`The "${label}" option must be one of: ${allowedValues}`); } } } /** * Async function to generate random bytes */ // export declare const randomBytesAsync: (arg1: number) => Promise; export const randomBytesAsync: (arg1: number) => Promise = promisify(randomBytes); /** * Async version of scrypt. */ // export declare const scryptAsync: (arg1: string, arg2: Buffer, arg3: number, arg4: ScryptOptions) => Promise; export const scryptAsync: (arg1: string, arg2: Buffer, arg3: number, arg4: ScryptOptions) => Promise = promisify(scrypt); export class PhcFormatter { /** * Serialize salt and hash with predefined options. */ serialize(salt: Buffer, hash: Buffer, options: any): string { return phc.serialize({ id: options.id, version: options.version, params: options.params, salt, hash, }); } /** * Deserialize a PHC string to an object */ deserialize(phcString: string): DeserializeResult { return phc.deserialize(phcString); } }