import { Binary, BinarySizes } from "./binary.ts";import { bufferToUuidHexString, uuidHexStringToBuffer, uuidValidateString,} from "./uuid_utils.ts";import { randomBytes } from "./parser/utils.ts";import { BSONTypeError } from "./error.ts";import { equals } from "../deps.ts";const BYTE_LENGTH = 16;
export type UUIDExtended = { $uuid: string;};
export class UUID { _bsontype = "UUID"; static cacheHexString: boolean;
#bytesBuffer: Uint8Array; #id?: string;
constructor(input?: string | Uint8Array | UUID) { if (typeof input === "undefined") { this.id = UUID.generate(); } else if (input instanceof UUID) { this.#bytesBuffer = input.id; this.#id = input.#id; } else if (ArrayBuffer.isView(input) && input.byteLength === BYTE_LENGTH) { this.id = input; } else if (typeof input === "string") { this.id = uuidHexStringToBuffer(input); } else { throw new BSONTypeError( "Argument passed in UUID constructor must be a UUID, a 16 byte Buffer or a 32/36 character hex string (dashes excluded/included, format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).", ); } this.#bytesBuffer = this.id; }
get id(): Uint8Array { return this.#bytesBuffer; }
set id(value: Uint8Array) { this.#bytesBuffer = value;
if (UUID.cacheHexString) { this.#id = bufferToUuidHexString(value); } }
toHexString(includeDashes = true): string { if (UUID.cacheHexString && this.#id) { return this.#id; }
const uuidHexString = bufferToUuidHexString(this.id, includeDashes);
if (UUID.cacheHexString) { this.#id = uuidHexString; }
return uuidHexString; }
toString(): string { return this.toHexString(); }
toJSON(): string { return this.toHexString(); }
equals(otherId: string | Uint8Array | UUID): boolean { if (!otherId) { return false; }
if (otherId instanceof UUID) { return equals(otherId.id, this.id); }
try { return equals(new UUID(otherId).id, this.id); } catch { return false; } }
toBinary(): Binary { return new Binary(this.id, BinarySizes.SUBTYPE_UUID); }
static generate(): Uint8Array { const bytes = randomBytes(BYTE_LENGTH);
bytes[6] = (bytes[6] & 0x0f) | 0x40; bytes[8] = (bytes[8] & 0x3f) | 0x80;
return bytes; }
static isValid(input: string | Uint8Array | UUID): boolean { if (!input) { return false; }
if (input instanceof UUID) { return true; }
if (typeof input === "string") { return uuidValidateString(input); }
if (input instanceof Uint8Array) { if (input.length !== BYTE_LENGTH) { return false; }
try { return parseInt(input[6].toString(16)[0], 10) === BinarySizes.SUBTYPE_UUID; } catch { return false; } }
return false; }
static createFromHexString(hexString: string): UUID { const buffer = uuidHexStringToBuffer(hexString); return new UUID(buffer); }
[Symbol.for("Deno.customInspect")](): string { return `new UUID("${this.toHexString()}")`; }}