import { crypto as wasmCrypto, digestAlgorithms as wasmDigestAlgorithms, } from "../_wasm_crypto/mod.ts";
const webCrypto = ((crypto) => ({
    getRandomValues: crypto.getRandomValues?.bind(crypto),
    randomUUID: crypto.randomUUID?.bind(crypto),
    subtle: {
        decrypt: crypto.subtle?.decrypt?.bind(crypto.subtle),
        deriveBits: crypto.subtle?.deriveBits?.bind(crypto.subtle),
        deriveKey: crypto.subtle?.deriveKey?.bind(crypto.subtle),
        digest: crypto.subtle?.digest?.bind(crypto.subtle),
        encrypt: crypto.subtle?.encrypt?.bind(crypto.subtle),
        exportKey: crypto.subtle?.exportKey?.bind(crypto.subtle),
        generateKey: crypto.subtle?.generateKey?.bind(crypto.subtle),
        importKey: crypto.subtle?.importKey?.bind(crypto.subtle),
        sign: crypto.subtle?.sign?.bind(crypto.subtle),
        unwrapKey: crypto.subtle?.unwrapKey?.bind(crypto.subtle),
        verify: crypto.subtle?.verify?.bind(crypto.subtle),
        wrapKey: crypto.subtle?.wrapKey?.bind(crypto.subtle),
    },
}))(globalThis.crypto);
const bufferSourceBytes = (data) => {
    let bytes;
    if (data instanceof Uint8Array) {
        bytes = data;
    }
    else if (ArrayBuffer.isView(data)) {
        bytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
    }
    else if (data instanceof ArrayBuffer) {
        bytes = new Uint8Array(data);
    }
    return bytes;
};
const stdCrypto = ((x) => x)({
    ...webCrypto,
    subtle: {
        ...webCrypto.subtle,
        async digest(algorithm, data) {
            const { name, length } = normalizeAlgorithm(algorithm);
            const bytes = bufferSourceBytes(data);
            if (webCryptoDigestAlgorithms.includes(name) &&
                bytes) {
                return webCrypto.subtle.digest(algorithm, bytes);
            }
            else if (wasmDigestAlgorithms.includes(name)) {
                if (bytes) {
                    return stdCrypto.subtle.digestSync(algorithm, bytes);
                }
                else if (data[Symbol.iterator]) {
                    return stdCrypto.subtle.digestSync(algorithm, data);
                }
                else if (data[Symbol.asyncIterator]) {
                    const context = new wasmCrypto.DigestContext(name);
                    for await (const chunk of data) {
                        const chunkBytes = bufferSourceBytes(chunk);
                        if (!chunkBytes) {
                            throw new TypeError("data contained chunk of the wrong type");
                        }
                        context.update(chunkBytes);
                    }
                    return context.digestAndDrop(length).buffer;
                }
                else {
                    throw new TypeError("data must be a BufferSource or [Async]Iterable<BufferSource>");
                }
            }
            else if (webCrypto.subtle?.digest) {
                return webCrypto.subtle.digest(algorithm, data);
            }
            else {
                throw new TypeError(`unsupported digest algorithm: ${algorithm}`);
            }
        },
        digestSync(algorithm, data) {
            algorithm = normalizeAlgorithm(algorithm);
            const bytes = bufferSourceBytes(data);
            if (bytes) {
                return wasmCrypto.digest(algorithm.name, bytes, algorithm.length)
                    .buffer;
            }
            else if (data[Symbol.iterator]) {
                const context = new wasmCrypto.DigestContext(algorithm.name);
                for (const chunk of data) {
                    const chunkBytes = bufferSourceBytes(chunk);
                    if (!chunkBytes) {
                        throw new TypeError("data contained chunk of the wrong type");
                    }
                    context.update(chunkBytes);
                }
                return context.digestAndDrop(algorithm.length).buffer;
            }
            else {
                throw new TypeError("data must be a BufferSource or Iterable<BufferSource>");
            }
        },
    },
});
const webCryptoDigestAlgorithms = [
    "SHA-384",
    "SHA-256",
    "SHA-512",
    "SHA-1",
];
const normalizeAlgorithm = (algorithm) => ((typeof algorithm === "string") ? { name: algorithm.toUpperCase() } : {
    ...algorithm,
    name: algorithm.name.toUpperCase(),
});
export { stdCrypto as crypto };
//# sourceMappingURL=data:application/json;base64,[encoded data, 13804 characters]