/**
 * Copyright © 2025 650 Industries.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */
const getHeadersConstructor = () => {
    if (typeof Headers !== 'undefined') {
        return Headers;
    }
    else {
        // NOTE(@kitten): The `assertRuntimeFetchAPISupport` helper will catch this. Currently only an issue in Jest
        return (globalThis.Headers ??
            class _MockHeaders {
                constructor() {
                    throw new Error('Runtime built-in Headers API is not available.');
                }
            });
    }
};
/**
 * An immutable version of the Fetch API's [`Headers`](https://developer.mozilla.org/en-US/docs/Web/API/Headers) object which prevents mutations.
 */
export class ImmutableHeaders extends getHeadersConstructor() {
    // TODO(@hassankhan): Merge with `ReadonlyHeaders` from `expo-router`
    #throwImmutableError() {
        throw new Error('This operation is not allowed on immutable headers.');
    }
    set() {
        this.#throwImmutableError();
    }
    append() {
        this.#throwImmutableError();
    }
    delete() {
        this.#throwImmutableError();
    }
}
/**
 * An immutable version of the Fetch API's [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) object which prevents mutations to the request body and headers.
 */
export class ImmutableRequest {
    #headers;
    #request;
    constructor(request) {
        this.#headers = new ImmutableHeaders(request.headers);
        this.#request = request;
    }
    get cache() {
        return this.#request.cache;
    }
    get credentials() {
        return this.#request.credentials;
    }
    get destination() {
        return this.#request.destination;
    }
    get integrity() {
        return this.#request.integrity;
    }
    get keepalive() {
        return this.#request.keepalive;
    }
    get method() {
        return this.#request.method;
    }
    get mode() {
        return this.#request.mode;
    }
    get redirect() {
        return this.#request.redirect;
    }
    get referrer() {
        return this.#request.referrer;
    }
    get referrerPolicy() {
        return this.#request.referrerPolicy;
    }
    get signal() {
        return this.#request.signal;
    }
    get url() {
        return this.#request.url;
    }
    get bodyUsed() {
        return this.#request.bodyUsed;
    }
    get duplex() {
        return this.#request.duplex;
    }
    get headers() {
        return this.#headers;
    }
    #throwImmutableBodyError() {
        throw new Error('This operation is not allowed on immutable requests.');
    }
    /** The request body is not accessible in immutable requests. */
    get body() {
        // NOTE(@kitten): `new Request(req.url, req)` may internally access `req.body` to copy the request
        // We can pretend it is `null`. Marking `bodyUsed` makes no sense here as it manipulates the subsequent
        // code paths, but pretending there was no body should be safe
        return null;
    }
    async arrayBuffer() {
        this.#throwImmutableBodyError();
    }
    async blob() {
        this.#throwImmutableBodyError();
    }
    async bytes() {
        this.#throwImmutableBodyError();
    }
    async formData() {
        this.#throwImmutableBodyError();
    }
    async json() {
        this.#throwImmutableBodyError();
    }
    async text() {
        this.#throwImmutableBodyError();
    }
    /**
     * Creates a mutable clone of the original request. This is provided as an escape hatch.
     */
    clone() {
        return this.#request.clone();
    }
}
// Add assertions to improve usage in non-standard environments.
export function assertRuntimeFetchAPISupport({ Request, Response, Headers, process, } = globalThis) {
    // Check if Request and Response are available.
    if (typeof Request === 'undefined' ||
        typeof Response === 'undefined' ||
        typeof Headers === 'undefined') {
        // Detect if `--no-experimental-fetch` flag is enabled and warn that it must be disabled.
        if (typeof process !== 'undefined' && process.env && process.env.NODE_OPTIONS) {
            const nodeOptions = process.env.NODE_OPTIONS;
            if (nodeOptions.includes('--no-experimental-fetch')) {
                throw new Error('NODE_OPTIONS="--no-experimental-fetch" is not supported with Expo server. Node.js built-in Request/Response APIs are required to continue.');
            }
        }
        // If Node.js is <18, throw an error.
        if (typeof process !== 'undefined' && process.version) {
            const version = process.version;
            const majorVersion = parseInt(version.replace(/v/g, '').split('.')[0], 10);
            if (majorVersion < 18) {
                throw new Error(`Node.js version ${majorVersion} is not supported. Upgrade to Node.js 20 or newer.`);
            }
        }
        // Default error event for missing APIs.
        throw new Error('Runtime built-in Request/Response/Headers APIs are not available. If running Node ensure that Node Fetch API, first available in Node.js 18, is enabled.');
    }
}
//# sourceMappingURL=ImmutableRequest.js.map