// Keep the key in memory as it should never change during the lifetime of the server in
// both development and production.
let __next_encryption_key_generation_promise = null;
let __next_loaded_action_key;
let __next_internal_development_raw_action_key;
export function arrayBufferToString(buffer) {
    const bytes = new Uint8Array(buffer);
    const len = bytes.byteLength;
    // @anonrig: V8 has a limit of 65535 arguments in a function.
    // For len < 65535, this is faster.
    // https://github.com/vercel/next.js/pull/56377#pullrequestreview-1656181623
    if (len < 65535) {
        return String.fromCharCode.apply(null, bytes);
    }
    let binary = "";
    for(let i = 0; i < len; i++){
        binary += String.fromCharCode(bytes[i]);
    }
    return binary;
}
export function stringToUint8Array(binary) {
    const len = binary.length;
    const arr = new Uint8Array(len);
    for(let i = 0; i < len; i++){
        arr[i] = binary.charCodeAt(i);
    }
    return arr;
}
export function encrypt(key, iv, data) {
    return crypto.subtle.encrypt({
        name: "AES-GCM",
        iv
    }, key, data);
}
export function decrypt(key, iv, data) {
    return crypto.subtle.decrypt({
        name: "AES-GCM",
        iv
    }, key, data);
}
export async function generateEncryptionKeyBase64(dev) {
    // For development, we just keep one key in memory for all actions.
    // This makes things faster.
    if (dev) {
        if (typeof __next_internal_development_raw_action_key !== "undefined") {
            return __next_internal_development_raw_action_key;
        }
    }
    // This avoids it being generated multiple times in parallel.
    if (!__next_encryption_key_generation_promise) {
        __next_encryption_key_generation_promise = new Promise(async (resolve, reject)=>{
            try {
                const key = await crypto.subtle.generateKey({
                    name: "AES-GCM",
                    length: 256
                }, true, [
                    "encrypt",
                    "decrypt"
                ]);
                const exported = await crypto.subtle.exportKey("raw", key);
                const b64 = btoa(arrayBufferToString(exported));
                resolve([
                    key,
                    b64
                ]);
            } catch (error) {
                reject(error);
            }
        });
    }
    const [key, b64] = await __next_encryption_key_generation_promise;
    __next_loaded_action_key = key;
    if (dev) {
        __next_internal_development_raw_action_key = b64;
    }
    return b64;
}
// This is a global singleton that is used to encode/decode the action bound args from
// the closure. This can't be using a AsyncLocalStorage as it might happen on the module
// level. Since the client reference manifest won't be mutated, let's use a global singleton
// to keep it.
const SERVER_ACTION_MANIFESTS_SINGLETON = Symbol.for("next.server.action-manifests");
export function setReferenceManifestsSingleton({ clientReferenceManifest, serverActionsManifest, serverModuleMap }) {
    // @ts-ignore
    globalThis[SERVER_ACTION_MANIFESTS_SINGLETON] = {
        clientReferenceManifest,
        serverActionsManifest,
        serverModuleMap
    };
}
export function getServerModuleMap() {
    const serverActionsManifestSingleton = globalThis[SERVER_ACTION_MANIFESTS_SINGLETON];
    if (!serverActionsManifestSingleton) {
        throw new Error("Missing manifest for Server Actions. This is a bug in Next.js");
    }
    return serverActionsManifestSingleton.serverModuleMap;
}
export function getClientReferenceManifestSingleton() {
    const serverActionsManifestSingleton = globalThis[SERVER_ACTION_MANIFESTS_SINGLETON];
    if (!serverActionsManifestSingleton) {
        throw new Error("Missing manifest for Server Actions. This is a bug in Next.js");
    }
    return serverActionsManifestSingleton.clientReferenceManifest;
}
export async function getActionEncryptionKey() {
    if (__next_loaded_action_key) {
        return __next_loaded_action_key;
    }
    const serverActionsManifestSingleton = globalThis[SERVER_ACTION_MANIFESTS_SINGLETON];
    if (!serverActionsManifestSingleton) {
        throw new Error("Missing manifest for Server Actions. This is a bug in Next.js");
    }
    const rawKey = process.env.NEXT_SERVER_ACTIONS_ENCRYPTION_KEY || serverActionsManifestSingleton.serverActionsManifest.encryptionKey;
    if (rawKey === undefined) {
        throw new Error("Missing encryption key for Server Actions");
    }
    __next_loaded_action_key = await crypto.subtle.importKey("raw", stringToUint8Array(atob(rawKey)), "AES-GCM", true, [
        "encrypt",
        "decrypt"
    ]);
    return __next_loaded_action_key;
}

//# sourceMappingURL=encryption-utils.js.map