🏡 index : quine-global/webdriverio.git

import type { local, remote } from 'webdriver'
import type { RequestWithOptions, RespondWithOptions } from './types.js'

type Overwrite<T> = Omit<T extends RequestWithOptions ? remote.NetworkContinueRequestParameters : remote.NetworkContinueResponseParameters, 'request'>

/**
 * parse request or response overwrites to make it compatible with Bidis protocol
 * @param overwrite request or response overwrite
 * @returns object to pass to the protocol
 */
export function parseOverwrite<
    T extends RequestWithOptions | RespondWithOptions
>(
    overwrite: T,
    request: local.NetworkBeforeRequestSentParameters | local.NetworkResponseCompletedParameters
): Overwrite<T> {
    const result: Overwrite<T> = {} as unknown as Overwrite<T>
    if ('body' in overwrite && overwrite.body) {
        const bodyOverwrite = typeof overwrite.body === 'function'
            ? overwrite.body(request as local.NetworkBeforeRequestSentParameters)
            : overwrite.body
        result.body = (bodyOverwrite?.type === 'string' || bodyOverwrite?.type === 'base64')
            ? bodyOverwrite
            : typeof bodyOverwrite === 'string'
                ? { type: 'string', value: bodyOverwrite }
                : { type: 'base64', value: btoa(JSON.stringify(bodyOverwrite || '')) }
    }

    if ('headers' in overwrite) {
        const headersOverwrite = typeof overwrite.headers === 'function'
            ? overwrite.headers(request as local.NetworkBeforeRequestSentParameters)
            : overwrite.headers
        result.headers = Object.entries(headersOverwrite || {}).map(([name, value]) => ({
            name,
            value: { type: 'string', value }
        }))
    }

    if ('cookies' in overwrite && overwrite.cookies) {
        const cookieOverwrite = typeof overwrite.cookies === 'function'
            ? overwrite.cookies(request as local.NetworkBeforeRequestSentParameters) || []
            : overwrite.cookies
        result.cookies = cookieOverwrite.map((cookie) => ({
            name: cookie.name,
            value: <remote.NetworkStringValue>{
                type: 'string',
                value: cookie.value
            },
            domain: cookie.domain,
            path: cookie.path,
            expires: cookie.expiry,
            httpOnly: cookie.httpOnly,
            secure: cookie.secure,
            sameSite: cookie.sameSite?.toLowerCase() as remote.NetworkSetCookieHeader['sameSite'],
        }))
    }

    if ('statusCode' in overwrite && overwrite.statusCode) {
        const statusCodeOverwrite = typeof overwrite.statusCode === 'function'
            ? overwrite.statusCode(request as local.NetworkResponseCompletedParameters)
            : overwrite.statusCode
        ;(result as RespondWithOptions).statusCode = statusCodeOverwrite
    }

    if ('method' in overwrite) {
        result.method = typeof overwrite.method === 'function'
            ? overwrite.method(request as local.NetworkBeforeRequestSentParameters)
            : overwrite.method
    }

    if ('url' in overwrite) {
        result.url = typeof overwrite.url === 'function'
            ? overwrite.url(request as local.NetworkBeforeRequestSentParameters)
            : overwrite.url
    }

    return result
}

export function getPatternParam (pattern: URLPattern, key: keyof Omit<remote.NetworkUrlPatternPattern, 'type'>) {
    if (key !== 'pathname' && pattern[key] === '*') {
        return
    }

    if (key === 'port' && pattern.port === '') {
        return pattern.protocol === 'https' ? '443' : '80'
    }

    return pattern[key].replaceAll('*', '\\*')
}