import { StytchAPIUnreachableError, StytchAPISchemaError, StytchAPIError } from './public/SDKErrors.mjs';

var RetriableErrorType = /*#__PURE__*/ function(RetriableErrorType) {
    RetriableErrorType["RequiredCaptcha"] = "CAPTCHA required";
    return RetriableErrorType;
}({});
class RetriableError extends Error {
    type;
    constructor(type){
        super(type);
        this.type = type;
    }
}
async function retriableFetchSDK({ method, finalURL, basicAuthHeader, xSDKClientHeader, xSDKParentHostHeader, body, retryCallback }) {
    let req = {
        method,
        finalURL,
        basicAuthHeader,
        xSDKClientHeader,
        xSDKParentHostHeader,
        body
    };
    try {
        return await baseFetchSDK(req);
    } catch (err) {
        if (err instanceof RetriableError) {
            req = await retryCallback(err, req);
            return await baseFetchSDK(req);
        }
        throw err;
    }
}
async function baseFetchSDK({ method, finalURL, basicAuthHeader, xSDKClientHeader, xSDKParentHostHeader, body }) {
    const headers = {
        Authorization: basicAuthHeader,
        'Content-Type': 'application/json',
        'X-SDK-Client': xSDKClientHeader
    };
    if (xSDKParentHostHeader) {
        headers['X-SDK-Parent-Host'] = xSDKParentHostHeader;
    }
    const fetchOpts = {
        method,
        headers,
        body: body && JSON.stringify(body),
        credentials: 'include'
    };
    let resp;
    try {
        resp = await fetch(finalURL, fetchOpts);
    /* eslint-disable  @typescript-eslint/no-explicit-any */ } catch (e) {
        if (e.message === 'Failed to fetch') {
            throw new StytchAPIUnreachableError('Unable to contact our servers.');
        }
        throw e;
    }
    // We only return 200 from WB endpoints, but just in case let's accept all 2xx errors
    if (resp.status <= 299) {
        try {
            const respData = await resp.json();
            return respData.data;
        } catch  {
            throw new StytchAPIUnreachableError('Invalid JSON response from our servers.');
        }
    }
    // 99% of errors will be well-formed JSON errors with an appropriate content-type set
    if (resp.status !== 200 && resp.headers.get('content-type')?.includes('application/json')) {
        let respError;
        try {
            respError = await resp.json();
        } catch  {
            // Error was not JSON- but the content type said it was! This means the server lied to us, which it should never do...
            throw new StytchAPIUnreachableError('Invalid or no response from server');
        }
        // If this looks like a JSONSchema validation error, it probably means the caller isn't using
        // typescript and gave us a bad type.
        if ('body' in respError || 'params' in respError || 'query' in respError) {
            throw new StytchAPISchemaError(respError);
        }
        throw new StytchAPIError(respError);
    }
    // Finally handle the other 1% of errors (Captcha errors, network errors, 503s, etc.)
    let respData;
    try {
        respData = await resp.text();
    } catch  {
        throw new StytchAPIUnreachableError('Invalid response from our servers.');
    }
    if (respData.includes('Captcha required')) {
        throw new RetriableError("CAPTCHA required");
    }
    throw new StytchAPIUnreachableError('Invalid response from our servers.');
}
async function baseSubmitFormSDK({ method, finalURL, basicAuthHeader, xSDKClientHeader, xSDKParentHostHeader, body }) {
    const bodyParams = body || {};
    const finalBody = {
        ...bodyParams,
        __Authorization: basicAuthHeader,
        '__X-SDK-Client': xSDKClientHeader
    };
    if (xSDKParentHostHeader) {
        finalBody['__X-SDK-Parent-Host'] = xSDKParentHostHeader;
    }
    const children = Object.entries(finalBody).map(([key, value])=>{
        const input = document.createElement('input');
        input.type = 'hidden';
        input.name = key;
        input.value = value;
        return input;
    });
    const form = document.createElement('form');
    form.method = method;
    form.action = finalURL;
    form.append(...children);
    document.body.appendChild(form);
    form.submit();
}

export { RetriableError, RetriableErrorType, baseFetchSDK, baseSubmitFormSDK, retriableFetchSDK };
//# sourceMappingURL=NetworkClient.mjs.map
