11cb0ef41Sopenharmony_ci'use strict'
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst { kConstruct } = require('./symbols')
41cb0ef41Sopenharmony_ciconst { urlEquals, fieldValues: getFieldValues } = require('./util')
51cb0ef41Sopenharmony_ciconst { kEnumerableProperty, isDisturbed } = require('../core/util')
61cb0ef41Sopenharmony_ciconst { kHeadersList } = require('../core/symbols')
71cb0ef41Sopenharmony_ciconst { webidl } = require('../fetch/webidl')
81cb0ef41Sopenharmony_ciconst { Response, cloneResponse } = require('../fetch/response')
91cb0ef41Sopenharmony_ciconst { Request } = require('../fetch/request')
101cb0ef41Sopenharmony_ciconst { kState, kHeaders, kGuard, kRealm } = require('../fetch/symbols')
111cb0ef41Sopenharmony_ciconst { fetching } = require('../fetch/index')
121cb0ef41Sopenharmony_ciconst { urlIsHttpHttpsScheme, createDeferredPromise, readAllBytes } = require('../fetch/util')
131cb0ef41Sopenharmony_ciconst assert = require('assert')
141cb0ef41Sopenharmony_ciconst { getGlobalDispatcher } = require('../global')
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci/**
171cb0ef41Sopenharmony_ci * @see https://w3c.github.io/ServiceWorker/#dfn-cache-batch-operation
181cb0ef41Sopenharmony_ci * @typedef {Object} CacheBatchOperation
191cb0ef41Sopenharmony_ci * @property {'delete' | 'put'} type
201cb0ef41Sopenharmony_ci * @property {any} request
211cb0ef41Sopenharmony_ci * @property {any} response
221cb0ef41Sopenharmony_ci * @property {import('../../types/cache').CacheQueryOptions} options
231cb0ef41Sopenharmony_ci */
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ci/**
261cb0ef41Sopenharmony_ci * @see https://w3c.github.io/ServiceWorker/#dfn-request-response-list
271cb0ef41Sopenharmony_ci * @typedef {[any, any][]} requestResponseList
281cb0ef41Sopenharmony_ci */
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ciclass Cache {
311cb0ef41Sopenharmony_ci  /**
321cb0ef41Sopenharmony_ci   * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-request-response-list
331cb0ef41Sopenharmony_ci   * @type {requestResponseList}
341cb0ef41Sopenharmony_ci   */
351cb0ef41Sopenharmony_ci  #relevantRequestResponseList
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci  constructor () {
381cb0ef41Sopenharmony_ci    if (arguments[0] !== kConstruct) {
391cb0ef41Sopenharmony_ci      webidl.illegalConstructor()
401cb0ef41Sopenharmony_ci    }
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci    this.#relevantRequestResponseList = arguments[1]
431cb0ef41Sopenharmony_ci  }
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci  async match (request, options = {}) {
461cb0ef41Sopenharmony_ci    webidl.brandCheck(this, Cache)
471cb0ef41Sopenharmony_ci    webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.match' })
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci    request = webidl.converters.RequestInfo(request)
501cb0ef41Sopenharmony_ci    options = webidl.converters.CacheQueryOptions(options)
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci    const p = await this.matchAll(request, options)
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci    if (p.length === 0) {
551cb0ef41Sopenharmony_ci      return
561cb0ef41Sopenharmony_ci    }
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci    return p[0]
591cb0ef41Sopenharmony_ci  }
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci  async matchAll (request = undefined, options = {}) {
621cb0ef41Sopenharmony_ci    webidl.brandCheck(this, Cache)
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci    if (request !== undefined) request = webidl.converters.RequestInfo(request)
651cb0ef41Sopenharmony_ci    options = webidl.converters.CacheQueryOptions(options)
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci    // 1.
681cb0ef41Sopenharmony_ci    let r = null
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ci    // 2.
711cb0ef41Sopenharmony_ci    if (request !== undefined) {
721cb0ef41Sopenharmony_ci      if (request instanceof Request) {
731cb0ef41Sopenharmony_ci        // 2.1.1
741cb0ef41Sopenharmony_ci        r = request[kState]
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci        // 2.1.2
771cb0ef41Sopenharmony_ci        if (r.method !== 'GET' && !options.ignoreMethod) {
781cb0ef41Sopenharmony_ci          return []
791cb0ef41Sopenharmony_ci        }
801cb0ef41Sopenharmony_ci      } else if (typeof request === 'string') {
811cb0ef41Sopenharmony_ci        // 2.2.1
821cb0ef41Sopenharmony_ci        r = new Request(request)[kState]
831cb0ef41Sopenharmony_ci      }
841cb0ef41Sopenharmony_ci    }
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci    // 5.
871cb0ef41Sopenharmony_ci    // 5.1
881cb0ef41Sopenharmony_ci    const responses = []
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci    // 5.2
911cb0ef41Sopenharmony_ci    if (request === undefined) {
921cb0ef41Sopenharmony_ci      // 5.2.1
931cb0ef41Sopenharmony_ci      for (const requestResponse of this.#relevantRequestResponseList) {
941cb0ef41Sopenharmony_ci        responses.push(requestResponse[1])
951cb0ef41Sopenharmony_ci      }
961cb0ef41Sopenharmony_ci    } else { // 5.3
971cb0ef41Sopenharmony_ci      // 5.3.1
981cb0ef41Sopenharmony_ci      const requestResponses = this.#queryCache(r, options)
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ci      // 5.3.2
1011cb0ef41Sopenharmony_ci      for (const requestResponse of requestResponses) {
1021cb0ef41Sopenharmony_ci        responses.push(requestResponse[1])
1031cb0ef41Sopenharmony_ci      }
1041cb0ef41Sopenharmony_ci    }
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci    // 5.4
1071cb0ef41Sopenharmony_ci    // We don't implement CORs so we don't need to loop over the responses, yay!
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_ci    // 5.5.1
1101cb0ef41Sopenharmony_ci    const responseList = []
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci    // 5.5.2
1131cb0ef41Sopenharmony_ci    for (const response of responses) {
1141cb0ef41Sopenharmony_ci      // 5.5.2.1
1151cb0ef41Sopenharmony_ci      const responseObject = new Response(response.body?.source ?? null)
1161cb0ef41Sopenharmony_ci      const body = responseObject[kState].body
1171cb0ef41Sopenharmony_ci      responseObject[kState] = response
1181cb0ef41Sopenharmony_ci      responseObject[kState].body = body
1191cb0ef41Sopenharmony_ci      responseObject[kHeaders][kHeadersList] = response.headersList
1201cb0ef41Sopenharmony_ci      responseObject[kHeaders][kGuard] = 'immutable'
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci      responseList.push(responseObject)
1231cb0ef41Sopenharmony_ci    }
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ci    // 6.
1261cb0ef41Sopenharmony_ci    return Object.freeze(responseList)
1271cb0ef41Sopenharmony_ci  }
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci  async add (request) {
1301cb0ef41Sopenharmony_ci    webidl.brandCheck(this, Cache)
1311cb0ef41Sopenharmony_ci    webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.add' })
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ci    request = webidl.converters.RequestInfo(request)
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci    // 1.
1361cb0ef41Sopenharmony_ci    const requests = [request]
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_ci    // 2.
1391cb0ef41Sopenharmony_ci    const responseArrayPromise = this.addAll(requests)
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_ci    // 3.
1421cb0ef41Sopenharmony_ci    return await responseArrayPromise
1431cb0ef41Sopenharmony_ci  }
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ci  async addAll (requests) {
1461cb0ef41Sopenharmony_ci    webidl.brandCheck(this, Cache)
1471cb0ef41Sopenharmony_ci    webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.addAll' })
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ci    requests = webidl.converters['sequence<RequestInfo>'](requests)
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ci    // 1.
1521cb0ef41Sopenharmony_ci    const responsePromises = []
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci    // 2.
1551cb0ef41Sopenharmony_ci    const requestList = []
1561cb0ef41Sopenharmony_ci
1571cb0ef41Sopenharmony_ci    // 3.
1581cb0ef41Sopenharmony_ci    for (const request of requests) {
1591cb0ef41Sopenharmony_ci      if (typeof request === 'string') {
1601cb0ef41Sopenharmony_ci        continue
1611cb0ef41Sopenharmony_ci      }
1621cb0ef41Sopenharmony_ci
1631cb0ef41Sopenharmony_ci      // 3.1
1641cb0ef41Sopenharmony_ci      const r = request[kState]
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ci      // 3.2
1671cb0ef41Sopenharmony_ci      if (!urlIsHttpHttpsScheme(r.url) || r.method !== 'GET') {
1681cb0ef41Sopenharmony_ci        throw webidl.errors.exception({
1691cb0ef41Sopenharmony_ci          header: 'Cache.addAll',
1701cb0ef41Sopenharmony_ci          message: 'Expected http/s scheme when method is not GET.'
1711cb0ef41Sopenharmony_ci        })
1721cb0ef41Sopenharmony_ci      }
1731cb0ef41Sopenharmony_ci    }
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_ci    // 4.
1761cb0ef41Sopenharmony_ci    /** @type {ReturnType<typeof fetching>[]} */
1771cb0ef41Sopenharmony_ci    const fetchControllers = []
1781cb0ef41Sopenharmony_ci
1791cb0ef41Sopenharmony_ci    // 5.
1801cb0ef41Sopenharmony_ci    for (const request of requests) {
1811cb0ef41Sopenharmony_ci      // 5.1
1821cb0ef41Sopenharmony_ci      const r = new Request(request)[kState]
1831cb0ef41Sopenharmony_ci
1841cb0ef41Sopenharmony_ci      // 5.2
1851cb0ef41Sopenharmony_ci      if (!urlIsHttpHttpsScheme(r.url)) {
1861cb0ef41Sopenharmony_ci        throw webidl.errors.exception({
1871cb0ef41Sopenharmony_ci          header: 'Cache.addAll',
1881cb0ef41Sopenharmony_ci          message: 'Expected http/s scheme.'
1891cb0ef41Sopenharmony_ci        })
1901cb0ef41Sopenharmony_ci      }
1911cb0ef41Sopenharmony_ci
1921cb0ef41Sopenharmony_ci      // 5.4
1931cb0ef41Sopenharmony_ci      r.initiator = 'fetch'
1941cb0ef41Sopenharmony_ci      r.destination = 'subresource'
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_ci      // 5.5
1971cb0ef41Sopenharmony_ci      requestList.push(r)
1981cb0ef41Sopenharmony_ci
1991cb0ef41Sopenharmony_ci      // 5.6
2001cb0ef41Sopenharmony_ci      const responsePromise = createDeferredPromise()
2011cb0ef41Sopenharmony_ci
2021cb0ef41Sopenharmony_ci      // 5.7
2031cb0ef41Sopenharmony_ci      fetchControllers.push(fetching({
2041cb0ef41Sopenharmony_ci        request: r,
2051cb0ef41Sopenharmony_ci        dispatcher: getGlobalDispatcher(),
2061cb0ef41Sopenharmony_ci        processResponse (response) {
2071cb0ef41Sopenharmony_ci          // 1.
2081cb0ef41Sopenharmony_ci          if (response.type === 'error' || response.status === 206 || response.status < 200 || response.status > 299) {
2091cb0ef41Sopenharmony_ci            responsePromise.reject(webidl.errors.exception({
2101cb0ef41Sopenharmony_ci              header: 'Cache.addAll',
2111cb0ef41Sopenharmony_ci              message: 'Received an invalid status code or the request failed.'
2121cb0ef41Sopenharmony_ci            }))
2131cb0ef41Sopenharmony_ci          } else if (response.headersList.contains('vary')) { // 2.
2141cb0ef41Sopenharmony_ci            // 2.1
2151cb0ef41Sopenharmony_ci            const fieldValues = getFieldValues(response.headersList.get('vary'))
2161cb0ef41Sopenharmony_ci
2171cb0ef41Sopenharmony_ci            // 2.2
2181cb0ef41Sopenharmony_ci            for (const fieldValue of fieldValues) {
2191cb0ef41Sopenharmony_ci              // 2.2.1
2201cb0ef41Sopenharmony_ci              if (fieldValue === '*') {
2211cb0ef41Sopenharmony_ci                responsePromise.reject(webidl.errors.exception({
2221cb0ef41Sopenharmony_ci                  header: 'Cache.addAll',
2231cb0ef41Sopenharmony_ci                  message: 'invalid vary field value'
2241cb0ef41Sopenharmony_ci                }))
2251cb0ef41Sopenharmony_ci
2261cb0ef41Sopenharmony_ci                for (const controller of fetchControllers) {
2271cb0ef41Sopenharmony_ci                  controller.abort()
2281cb0ef41Sopenharmony_ci                }
2291cb0ef41Sopenharmony_ci
2301cb0ef41Sopenharmony_ci                return
2311cb0ef41Sopenharmony_ci              }
2321cb0ef41Sopenharmony_ci            }
2331cb0ef41Sopenharmony_ci          }
2341cb0ef41Sopenharmony_ci        },
2351cb0ef41Sopenharmony_ci        processResponseEndOfBody (response) {
2361cb0ef41Sopenharmony_ci          // 1.
2371cb0ef41Sopenharmony_ci          if (response.aborted) {
2381cb0ef41Sopenharmony_ci            responsePromise.reject(new DOMException('aborted', 'AbortError'))
2391cb0ef41Sopenharmony_ci            return
2401cb0ef41Sopenharmony_ci          }
2411cb0ef41Sopenharmony_ci
2421cb0ef41Sopenharmony_ci          // 2.
2431cb0ef41Sopenharmony_ci          responsePromise.resolve(response)
2441cb0ef41Sopenharmony_ci        }
2451cb0ef41Sopenharmony_ci      }))
2461cb0ef41Sopenharmony_ci
2471cb0ef41Sopenharmony_ci      // 5.8
2481cb0ef41Sopenharmony_ci      responsePromises.push(responsePromise.promise)
2491cb0ef41Sopenharmony_ci    }
2501cb0ef41Sopenharmony_ci
2511cb0ef41Sopenharmony_ci    // 6.
2521cb0ef41Sopenharmony_ci    const p = Promise.all(responsePromises)
2531cb0ef41Sopenharmony_ci
2541cb0ef41Sopenharmony_ci    // 7.
2551cb0ef41Sopenharmony_ci    const responses = await p
2561cb0ef41Sopenharmony_ci
2571cb0ef41Sopenharmony_ci    // 7.1
2581cb0ef41Sopenharmony_ci    const operations = []
2591cb0ef41Sopenharmony_ci
2601cb0ef41Sopenharmony_ci    // 7.2
2611cb0ef41Sopenharmony_ci    let index = 0
2621cb0ef41Sopenharmony_ci
2631cb0ef41Sopenharmony_ci    // 7.3
2641cb0ef41Sopenharmony_ci    for (const response of responses) {
2651cb0ef41Sopenharmony_ci      // 7.3.1
2661cb0ef41Sopenharmony_ci      /** @type {CacheBatchOperation} */
2671cb0ef41Sopenharmony_ci      const operation = {
2681cb0ef41Sopenharmony_ci        type: 'put', // 7.3.2
2691cb0ef41Sopenharmony_ci        request: requestList[index], // 7.3.3
2701cb0ef41Sopenharmony_ci        response // 7.3.4
2711cb0ef41Sopenharmony_ci      }
2721cb0ef41Sopenharmony_ci
2731cb0ef41Sopenharmony_ci      operations.push(operation) // 7.3.5
2741cb0ef41Sopenharmony_ci
2751cb0ef41Sopenharmony_ci      index++ // 7.3.6
2761cb0ef41Sopenharmony_ci    }
2771cb0ef41Sopenharmony_ci
2781cb0ef41Sopenharmony_ci    // 7.5
2791cb0ef41Sopenharmony_ci    const cacheJobPromise = createDeferredPromise()
2801cb0ef41Sopenharmony_ci
2811cb0ef41Sopenharmony_ci    // 7.6.1
2821cb0ef41Sopenharmony_ci    let errorData = null
2831cb0ef41Sopenharmony_ci
2841cb0ef41Sopenharmony_ci    // 7.6.2
2851cb0ef41Sopenharmony_ci    try {
2861cb0ef41Sopenharmony_ci      this.#batchCacheOperations(operations)
2871cb0ef41Sopenharmony_ci    } catch (e) {
2881cb0ef41Sopenharmony_ci      errorData = e
2891cb0ef41Sopenharmony_ci    }
2901cb0ef41Sopenharmony_ci
2911cb0ef41Sopenharmony_ci    // 7.6.3
2921cb0ef41Sopenharmony_ci    queueMicrotask(() => {
2931cb0ef41Sopenharmony_ci      // 7.6.3.1
2941cb0ef41Sopenharmony_ci      if (errorData === null) {
2951cb0ef41Sopenharmony_ci        cacheJobPromise.resolve(undefined)
2961cb0ef41Sopenharmony_ci      } else {
2971cb0ef41Sopenharmony_ci        // 7.6.3.2
2981cb0ef41Sopenharmony_ci        cacheJobPromise.reject(errorData)
2991cb0ef41Sopenharmony_ci      }
3001cb0ef41Sopenharmony_ci    })
3011cb0ef41Sopenharmony_ci
3021cb0ef41Sopenharmony_ci    // 7.7
3031cb0ef41Sopenharmony_ci    return cacheJobPromise.promise
3041cb0ef41Sopenharmony_ci  }
3051cb0ef41Sopenharmony_ci
3061cb0ef41Sopenharmony_ci  async put (request, response) {
3071cb0ef41Sopenharmony_ci    webidl.brandCheck(this, Cache)
3081cb0ef41Sopenharmony_ci    webidl.argumentLengthCheck(arguments, 2, { header: 'Cache.put' })
3091cb0ef41Sopenharmony_ci
3101cb0ef41Sopenharmony_ci    request = webidl.converters.RequestInfo(request)
3111cb0ef41Sopenharmony_ci    response = webidl.converters.Response(response)
3121cb0ef41Sopenharmony_ci
3131cb0ef41Sopenharmony_ci    // 1.
3141cb0ef41Sopenharmony_ci    let innerRequest = null
3151cb0ef41Sopenharmony_ci
3161cb0ef41Sopenharmony_ci    // 2.
3171cb0ef41Sopenharmony_ci    if (request instanceof Request) {
3181cb0ef41Sopenharmony_ci      innerRequest = request[kState]
3191cb0ef41Sopenharmony_ci    } else { // 3.
3201cb0ef41Sopenharmony_ci      innerRequest = new Request(request)[kState]
3211cb0ef41Sopenharmony_ci    }
3221cb0ef41Sopenharmony_ci
3231cb0ef41Sopenharmony_ci    // 4.
3241cb0ef41Sopenharmony_ci    if (!urlIsHttpHttpsScheme(innerRequest.url) || innerRequest.method !== 'GET') {
3251cb0ef41Sopenharmony_ci      throw webidl.errors.exception({
3261cb0ef41Sopenharmony_ci        header: 'Cache.put',
3271cb0ef41Sopenharmony_ci        message: 'Expected an http/s scheme when method is not GET'
3281cb0ef41Sopenharmony_ci      })
3291cb0ef41Sopenharmony_ci    }
3301cb0ef41Sopenharmony_ci
3311cb0ef41Sopenharmony_ci    // 5.
3321cb0ef41Sopenharmony_ci    const innerResponse = response[kState]
3331cb0ef41Sopenharmony_ci
3341cb0ef41Sopenharmony_ci    // 6.
3351cb0ef41Sopenharmony_ci    if (innerResponse.status === 206) {
3361cb0ef41Sopenharmony_ci      throw webidl.errors.exception({
3371cb0ef41Sopenharmony_ci        header: 'Cache.put',
3381cb0ef41Sopenharmony_ci        message: 'Got 206 status'
3391cb0ef41Sopenharmony_ci      })
3401cb0ef41Sopenharmony_ci    }
3411cb0ef41Sopenharmony_ci
3421cb0ef41Sopenharmony_ci    // 7.
3431cb0ef41Sopenharmony_ci    if (innerResponse.headersList.contains('vary')) {
3441cb0ef41Sopenharmony_ci      // 7.1.
3451cb0ef41Sopenharmony_ci      const fieldValues = getFieldValues(innerResponse.headersList.get('vary'))
3461cb0ef41Sopenharmony_ci
3471cb0ef41Sopenharmony_ci      // 7.2.
3481cb0ef41Sopenharmony_ci      for (const fieldValue of fieldValues) {
3491cb0ef41Sopenharmony_ci        // 7.2.1
3501cb0ef41Sopenharmony_ci        if (fieldValue === '*') {
3511cb0ef41Sopenharmony_ci          throw webidl.errors.exception({
3521cb0ef41Sopenharmony_ci            header: 'Cache.put',
3531cb0ef41Sopenharmony_ci            message: 'Got * vary field value'
3541cb0ef41Sopenharmony_ci          })
3551cb0ef41Sopenharmony_ci        }
3561cb0ef41Sopenharmony_ci      }
3571cb0ef41Sopenharmony_ci    }
3581cb0ef41Sopenharmony_ci
3591cb0ef41Sopenharmony_ci    // 8.
3601cb0ef41Sopenharmony_ci    if (innerResponse.body && (isDisturbed(innerResponse.body.stream) || innerResponse.body.stream.locked)) {
3611cb0ef41Sopenharmony_ci      throw webidl.errors.exception({
3621cb0ef41Sopenharmony_ci        header: 'Cache.put',
3631cb0ef41Sopenharmony_ci        message: 'Response body is locked or disturbed'
3641cb0ef41Sopenharmony_ci      })
3651cb0ef41Sopenharmony_ci    }
3661cb0ef41Sopenharmony_ci
3671cb0ef41Sopenharmony_ci    // 9.
3681cb0ef41Sopenharmony_ci    const clonedResponse = cloneResponse(innerResponse)
3691cb0ef41Sopenharmony_ci
3701cb0ef41Sopenharmony_ci    // 10.
3711cb0ef41Sopenharmony_ci    const bodyReadPromise = createDeferredPromise()
3721cb0ef41Sopenharmony_ci
3731cb0ef41Sopenharmony_ci    // 11.
3741cb0ef41Sopenharmony_ci    if (innerResponse.body != null) {
3751cb0ef41Sopenharmony_ci      // 11.1
3761cb0ef41Sopenharmony_ci      const stream = innerResponse.body.stream
3771cb0ef41Sopenharmony_ci
3781cb0ef41Sopenharmony_ci      // 11.2
3791cb0ef41Sopenharmony_ci      const reader = stream.getReader()
3801cb0ef41Sopenharmony_ci
3811cb0ef41Sopenharmony_ci      // 11.3
3821cb0ef41Sopenharmony_ci      readAllBytes(reader).then(bodyReadPromise.resolve, bodyReadPromise.reject)
3831cb0ef41Sopenharmony_ci    } else {
3841cb0ef41Sopenharmony_ci      bodyReadPromise.resolve(undefined)
3851cb0ef41Sopenharmony_ci    }
3861cb0ef41Sopenharmony_ci
3871cb0ef41Sopenharmony_ci    // 12.
3881cb0ef41Sopenharmony_ci    /** @type {CacheBatchOperation[]} */
3891cb0ef41Sopenharmony_ci    const operations = []
3901cb0ef41Sopenharmony_ci
3911cb0ef41Sopenharmony_ci    // 13.
3921cb0ef41Sopenharmony_ci    /** @type {CacheBatchOperation} */
3931cb0ef41Sopenharmony_ci    const operation = {
3941cb0ef41Sopenharmony_ci      type: 'put', // 14.
3951cb0ef41Sopenharmony_ci      request: innerRequest, // 15.
3961cb0ef41Sopenharmony_ci      response: clonedResponse // 16.
3971cb0ef41Sopenharmony_ci    }
3981cb0ef41Sopenharmony_ci
3991cb0ef41Sopenharmony_ci    // 17.
4001cb0ef41Sopenharmony_ci    operations.push(operation)
4011cb0ef41Sopenharmony_ci
4021cb0ef41Sopenharmony_ci    // 19.
4031cb0ef41Sopenharmony_ci    const bytes = await bodyReadPromise.promise
4041cb0ef41Sopenharmony_ci
4051cb0ef41Sopenharmony_ci    if (clonedResponse.body != null) {
4061cb0ef41Sopenharmony_ci      clonedResponse.body.source = bytes
4071cb0ef41Sopenharmony_ci    }
4081cb0ef41Sopenharmony_ci
4091cb0ef41Sopenharmony_ci    // 19.1
4101cb0ef41Sopenharmony_ci    const cacheJobPromise = createDeferredPromise()
4111cb0ef41Sopenharmony_ci
4121cb0ef41Sopenharmony_ci    // 19.2.1
4131cb0ef41Sopenharmony_ci    let errorData = null
4141cb0ef41Sopenharmony_ci
4151cb0ef41Sopenharmony_ci    // 19.2.2
4161cb0ef41Sopenharmony_ci    try {
4171cb0ef41Sopenharmony_ci      this.#batchCacheOperations(operations)
4181cb0ef41Sopenharmony_ci    } catch (e) {
4191cb0ef41Sopenharmony_ci      errorData = e
4201cb0ef41Sopenharmony_ci    }
4211cb0ef41Sopenharmony_ci
4221cb0ef41Sopenharmony_ci    // 19.2.3
4231cb0ef41Sopenharmony_ci    queueMicrotask(() => {
4241cb0ef41Sopenharmony_ci      // 19.2.3.1
4251cb0ef41Sopenharmony_ci      if (errorData === null) {
4261cb0ef41Sopenharmony_ci        cacheJobPromise.resolve()
4271cb0ef41Sopenharmony_ci      } else { // 19.2.3.2
4281cb0ef41Sopenharmony_ci        cacheJobPromise.reject(errorData)
4291cb0ef41Sopenharmony_ci      }
4301cb0ef41Sopenharmony_ci    })
4311cb0ef41Sopenharmony_ci
4321cb0ef41Sopenharmony_ci    return cacheJobPromise.promise
4331cb0ef41Sopenharmony_ci  }
4341cb0ef41Sopenharmony_ci
4351cb0ef41Sopenharmony_ci  async delete (request, options = {}) {
4361cb0ef41Sopenharmony_ci    webidl.brandCheck(this, Cache)
4371cb0ef41Sopenharmony_ci    webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.delete' })
4381cb0ef41Sopenharmony_ci
4391cb0ef41Sopenharmony_ci    request = webidl.converters.RequestInfo(request)
4401cb0ef41Sopenharmony_ci    options = webidl.converters.CacheQueryOptions(options)
4411cb0ef41Sopenharmony_ci
4421cb0ef41Sopenharmony_ci    /**
4431cb0ef41Sopenharmony_ci     * @type {Request}
4441cb0ef41Sopenharmony_ci     */
4451cb0ef41Sopenharmony_ci    let r = null
4461cb0ef41Sopenharmony_ci
4471cb0ef41Sopenharmony_ci    if (request instanceof Request) {
4481cb0ef41Sopenharmony_ci      r = request[kState]
4491cb0ef41Sopenharmony_ci
4501cb0ef41Sopenharmony_ci      if (r.method !== 'GET' && !options.ignoreMethod) {
4511cb0ef41Sopenharmony_ci        return false
4521cb0ef41Sopenharmony_ci      }
4531cb0ef41Sopenharmony_ci    } else {
4541cb0ef41Sopenharmony_ci      assert(typeof request === 'string')
4551cb0ef41Sopenharmony_ci
4561cb0ef41Sopenharmony_ci      r = new Request(request)[kState]
4571cb0ef41Sopenharmony_ci    }
4581cb0ef41Sopenharmony_ci
4591cb0ef41Sopenharmony_ci    /** @type {CacheBatchOperation[]} */
4601cb0ef41Sopenharmony_ci    const operations = []
4611cb0ef41Sopenharmony_ci
4621cb0ef41Sopenharmony_ci    /** @type {CacheBatchOperation} */
4631cb0ef41Sopenharmony_ci    const operation = {
4641cb0ef41Sopenharmony_ci      type: 'delete',
4651cb0ef41Sopenharmony_ci      request: r,
4661cb0ef41Sopenharmony_ci      options
4671cb0ef41Sopenharmony_ci    }
4681cb0ef41Sopenharmony_ci
4691cb0ef41Sopenharmony_ci    operations.push(operation)
4701cb0ef41Sopenharmony_ci
4711cb0ef41Sopenharmony_ci    const cacheJobPromise = createDeferredPromise()
4721cb0ef41Sopenharmony_ci
4731cb0ef41Sopenharmony_ci    let errorData = null
4741cb0ef41Sopenharmony_ci    let requestResponses
4751cb0ef41Sopenharmony_ci
4761cb0ef41Sopenharmony_ci    try {
4771cb0ef41Sopenharmony_ci      requestResponses = this.#batchCacheOperations(operations)
4781cb0ef41Sopenharmony_ci    } catch (e) {
4791cb0ef41Sopenharmony_ci      errorData = e
4801cb0ef41Sopenharmony_ci    }
4811cb0ef41Sopenharmony_ci
4821cb0ef41Sopenharmony_ci    queueMicrotask(() => {
4831cb0ef41Sopenharmony_ci      if (errorData === null) {
4841cb0ef41Sopenharmony_ci        cacheJobPromise.resolve(!!requestResponses?.length)
4851cb0ef41Sopenharmony_ci      } else {
4861cb0ef41Sopenharmony_ci        cacheJobPromise.reject(errorData)
4871cb0ef41Sopenharmony_ci      }
4881cb0ef41Sopenharmony_ci    })
4891cb0ef41Sopenharmony_ci
4901cb0ef41Sopenharmony_ci    return cacheJobPromise.promise
4911cb0ef41Sopenharmony_ci  }
4921cb0ef41Sopenharmony_ci
4931cb0ef41Sopenharmony_ci  /**
4941cb0ef41Sopenharmony_ci   * @see https://w3c.github.io/ServiceWorker/#dom-cache-keys
4951cb0ef41Sopenharmony_ci   * @param {any} request
4961cb0ef41Sopenharmony_ci   * @param {import('../../types/cache').CacheQueryOptions} options
4971cb0ef41Sopenharmony_ci   * @returns {readonly Request[]}
4981cb0ef41Sopenharmony_ci   */
4991cb0ef41Sopenharmony_ci  async keys (request = undefined, options = {}) {
5001cb0ef41Sopenharmony_ci    webidl.brandCheck(this, Cache)
5011cb0ef41Sopenharmony_ci
5021cb0ef41Sopenharmony_ci    if (request !== undefined) request = webidl.converters.RequestInfo(request)
5031cb0ef41Sopenharmony_ci    options = webidl.converters.CacheQueryOptions(options)
5041cb0ef41Sopenharmony_ci
5051cb0ef41Sopenharmony_ci    // 1.
5061cb0ef41Sopenharmony_ci    let r = null
5071cb0ef41Sopenharmony_ci
5081cb0ef41Sopenharmony_ci    // 2.
5091cb0ef41Sopenharmony_ci    if (request !== undefined) {
5101cb0ef41Sopenharmony_ci      // 2.1
5111cb0ef41Sopenharmony_ci      if (request instanceof Request) {
5121cb0ef41Sopenharmony_ci        // 2.1.1
5131cb0ef41Sopenharmony_ci        r = request[kState]
5141cb0ef41Sopenharmony_ci
5151cb0ef41Sopenharmony_ci        // 2.1.2
5161cb0ef41Sopenharmony_ci        if (r.method !== 'GET' && !options.ignoreMethod) {
5171cb0ef41Sopenharmony_ci          return []
5181cb0ef41Sopenharmony_ci        }
5191cb0ef41Sopenharmony_ci      } else if (typeof request === 'string') { // 2.2
5201cb0ef41Sopenharmony_ci        r = new Request(request)[kState]
5211cb0ef41Sopenharmony_ci      }
5221cb0ef41Sopenharmony_ci    }
5231cb0ef41Sopenharmony_ci
5241cb0ef41Sopenharmony_ci    // 4.
5251cb0ef41Sopenharmony_ci    const promise = createDeferredPromise()
5261cb0ef41Sopenharmony_ci
5271cb0ef41Sopenharmony_ci    // 5.
5281cb0ef41Sopenharmony_ci    // 5.1
5291cb0ef41Sopenharmony_ci    const requests = []
5301cb0ef41Sopenharmony_ci
5311cb0ef41Sopenharmony_ci    // 5.2
5321cb0ef41Sopenharmony_ci    if (request === undefined) {
5331cb0ef41Sopenharmony_ci      // 5.2.1
5341cb0ef41Sopenharmony_ci      for (const requestResponse of this.#relevantRequestResponseList) {
5351cb0ef41Sopenharmony_ci        // 5.2.1.1
5361cb0ef41Sopenharmony_ci        requests.push(requestResponse[0])
5371cb0ef41Sopenharmony_ci      }
5381cb0ef41Sopenharmony_ci    } else { // 5.3
5391cb0ef41Sopenharmony_ci      // 5.3.1
5401cb0ef41Sopenharmony_ci      const requestResponses = this.#queryCache(r, options)
5411cb0ef41Sopenharmony_ci
5421cb0ef41Sopenharmony_ci      // 5.3.2
5431cb0ef41Sopenharmony_ci      for (const requestResponse of requestResponses) {
5441cb0ef41Sopenharmony_ci        // 5.3.2.1
5451cb0ef41Sopenharmony_ci        requests.push(requestResponse[0])
5461cb0ef41Sopenharmony_ci      }
5471cb0ef41Sopenharmony_ci    }
5481cb0ef41Sopenharmony_ci
5491cb0ef41Sopenharmony_ci    // 5.4
5501cb0ef41Sopenharmony_ci    queueMicrotask(() => {
5511cb0ef41Sopenharmony_ci      // 5.4.1
5521cb0ef41Sopenharmony_ci      const requestList = []
5531cb0ef41Sopenharmony_ci
5541cb0ef41Sopenharmony_ci      // 5.4.2
5551cb0ef41Sopenharmony_ci      for (const request of requests) {
5561cb0ef41Sopenharmony_ci        const requestObject = new Request('https://a')
5571cb0ef41Sopenharmony_ci        requestObject[kState] = request
5581cb0ef41Sopenharmony_ci        requestObject[kHeaders][kHeadersList] = request.headersList
5591cb0ef41Sopenharmony_ci        requestObject[kHeaders][kGuard] = 'immutable'
5601cb0ef41Sopenharmony_ci        requestObject[kRealm] = request.client
5611cb0ef41Sopenharmony_ci
5621cb0ef41Sopenharmony_ci        // 5.4.2.1
5631cb0ef41Sopenharmony_ci        requestList.push(requestObject)
5641cb0ef41Sopenharmony_ci      }
5651cb0ef41Sopenharmony_ci
5661cb0ef41Sopenharmony_ci      // 5.4.3
5671cb0ef41Sopenharmony_ci      promise.resolve(Object.freeze(requestList))
5681cb0ef41Sopenharmony_ci    })
5691cb0ef41Sopenharmony_ci
5701cb0ef41Sopenharmony_ci    return promise.promise
5711cb0ef41Sopenharmony_ci  }
5721cb0ef41Sopenharmony_ci
5731cb0ef41Sopenharmony_ci  /**
5741cb0ef41Sopenharmony_ci   * @see https://w3c.github.io/ServiceWorker/#batch-cache-operations-algorithm
5751cb0ef41Sopenharmony_ci   * @param {CacheBatchOperation[]} operations
5761cb0ef41Sopenharmony_ci   * @returns {requestResponseList}
5771cb0ef41Sopenharmony_ci   */
5781cb0ef41Sopenharmony_ci  #batchCacheOperations (operations) {
5791cb0ef41Sopenharmony_ci    // 1.
5801cb0ef41Sopenharmony_ci    const cache = this.#relevantRequestResponseList
5811cb0ef41Sopenharmony_ci
5821cb0ef41Sopenharmony_ci    // 2.
5831cb0ef41Sopenharmony_ci    const backupCache = [...cache]
5841cb0ef41Sopenharmony_ci
5851cb0ef41Sopenharmony_ci    // 3.
5861cb0ef41Sopenharmony_ci    const addedItems = []
5871cb0ef41Sopenharmony_ci
5881cb0ef41Sopenharmony_ci    // 4.1
5891cb0ef41Sopenharmony_ci    const resultList = []
5901cb0ef41Sopenharmony_ci
5911cb0ef41Sopenharmony_ci    try {
5921cb0ef41Sopenharmony_ci      // 4.2
5931cb0ef41Sopenharmony_ci      for (const operation of operations) {
5941cb0ef41Sopenharmony_ci        // 4.2.1
5951cb0ef41Sopenharmony_ci        if (operation.type !== 'delete' && operation.type !== 'put') {
5961cb0ef41Sopenharmony_ci          throw webidl.errors.exception({
5971cb0ef41Sopenharmony_ci            header: 'Cache.#batchCacheOperations',
5981cb0ef41Sopenharmony_ci            message: 'operation type does not match "delete" or "put"'
5991cb0ef41Sopenharmony_ci          })
6001cb0ef41Sopenharmony_ci        }
6011cb0ef41Sopenharmony_ci
6021cb0ef41Sopenharmony_ci        // 4.2.2
6031cb0ef41Sopenharmony_ci        if (operation.type === 'delete' && operation.response != null) {
6041cb0ef41Sopenharmony_ci          throw webidl.errors.exception({
6051cb0ef41Sopenharmony_ci            header: 'Cache.#batchCacheOperations',
6061cb0ef41Sopenharmony_ci            message: 'delete operation should not have an associated response'
6071cb0ef41Sopenharmony_ci          })
6081cb0ef41Sopenharmony_ci        }
6091cb0ef41Sopenharmony_ci
6101cb0ef41Sopenharmony_ci        // 4.2.3
6111cb0ef41Sopenharmony_ci        if (this.#queryCache(operation.request, operation.options, addedItems).length) {
6121cb0ef41Sopenharmony_ci          throw new DOMException('???', 'InvalidStateError')
6131cb0ef41Sopenharmony_ci        }
6141cb0ef41Sopenharmony_ci
6151cb0ef41Sopenharmony_ci        // 4.2.4
6161cb0ef41Sopenharmony_ci        let requestResponses
6171cb0ef41Sopenharmony_ci
6181cb0ef41Sopenharmony_ci        // 4.2.5
6191cb0ef41Sopenharmony_ci        if (operation.type === 'delete') {
6201cb0ef41Sopenharmony_ci          // 4.2.5.1
6211cb0ef41Sopenharmony_ci          requestResponses = this.#queryCache(operation.request, operation.options)
6221cb0ef41Sopenharmony_ci
6231cb0ef41Sopenharmony_ci          // TODO: the spec is wrong, this is needed to pass WPTs
6241cb0ef41Sopenharmony_ci          if (requestResponses.length === 0) {
6251cb0ef41Sopenharmony_ci            return []
6261cb0ef41Sopenharmony_ci          }
6271cb0ef41Sopenharmony_ci
6281cb0ef41Sopenharmony_ci          // 4.2.5.2
6291cb0ef41Sopenharmony_ci          for (const requestResponse of requestResponses) {
6301cb0ef41Sopenharmony_ci            const idx = cache.indexOf(requestResponse)
6311cb0ef41Sopenharmony_ci            assert(idx !== -1)
6321cb0ef41Sopenharmony_ci
6331cb0ef41Sopenharmony_ci            // 4.2.5.2.1
6341cb0ef41Sopenharmony_ci            cache.splice(idx, 1)
6351cb0ef41Sopenharmony_ci          }
6361cb0ef41Sopenharmony_ci        } else if (operation.type === 'put') { // 4.2.6
6371cb0ef41Sopenharmony_ci          // 4.2.6.1
6381cb0ef41Sopenharmony_ci          if (operation.response == null) {
6391cb0ef41Sopenharmony_ci            throw webidl.errors.exception({
6401cb0ef41Sopenharmony_ci              header: 'Cache.#batchCacheOperations',
6411cb0ef41Sopenharmony_ci              message: 'put operation should have an associated response'
6421cb0ef41Sopenharmony_ci            })
6431cb0ef41Sopenharmony_ci          }
6441cb0ef41Sopenharmony_ci
6451cb0ef41Sopenharmony_ci          // 4.2.6.2
6461cb0ef41Sopenharmony_ci          const r = operation.request
6471cb0ef41Sopenharmony_ci
6481cb0ef41Sopenharmony_ci          // 4.2.6.3
6491cb0ef41Sopenharmony_ci          if (!urlIsHttpHttpsScheme(r.url)) {
6501cb0ef41Sopenharmony_ci            throw webidl.errors.exception({
6511cb0ef41Sopenharmony_ci              header: 'Cache.#batchCacheOperations',
6521cb0ef41Sopenharmony_ci              message: 'expected http or https scheme'
6531cb0ef41Sopenharmony_ci            })
6541cb0ef41Sopenharmony_ci          }
6551cb0ef41Sopenharmony_ci
6561cb0ef41Sopenharmony_ci          // 4.2.6.4
6571cb0ef41Sopenharmony_ci          if (r.method !== 'GET') {
6581cb0ef41Sopenharmony_ci            throw webidl.errors.exception({
6591cb0ef41Sopenharmony_ci              header: 'Cache.#batchCacheOperations',
6601cb0ef41Sopenharmony_ci              message: 'not get method'
6611cb0ef41Sopenharmony_ci            })
6621cb0ef41Sopenharmony_ci          }
6631cb0ef41Sopenharmony_ci
6641cb0ef41Sopenharmony_ci          // 4.2.6.5
6651cb0ef41Sopenharmony_ci          if (operation.options != null) {
6661cb0ef41Sopenharmony_ci            throw webidl.errors.exception({
6671cb0ef41Sopenharmony_ci              header: 'Cache.#batchCacheOperations',
6681cb0ef41Sopenharmony_ci              message: 'options must not be defined'
6691cb0ef41Sopenharmony_ci            })
6701cb0ef41Sopenharmony_ci          }
6711cb0ef41Sopenharmony_ci
6721cb0ef41Sopenharmony_ci          // 4.2.6.6
6731cb0ef41Sopenharmony_ci          requestResponses = this.#queryCache(operation.request)
6741cb0ef41Sopenharmony_ci
6751cb0ef41Sopenharmony_ci          // 4.2.6.7
6761cb0ef41Sopenharmony_ci          for (const requestResponse of requestResponses) {
6771cb0ef41Sopenharmony_ci            const idx = cache.indexOf(requestResponse)
6781cb0ef41Sopenharmony_ci            assert(idx !== -1)
6791cb0ef41Sopenharmony_ci
6801cb0ef41Sopenharmony_ci            // 4.2.6.7.1
6811cb0ef41Sopenharmony_ci            cache.splice(idx, 1)
6821cb0ef41Sopenharmony_ci          }
6831cb0ef41Sopenharmony_ci
6841cb0ef41Sopenharmony_ci          // 4.2.6.8
6851cb0ef41Sopenharmony_ci          cache.push([operation.request, operation.response])
6861cb0ef41Sopenharmony_ci
6871cb0ef41Sopenharmony_ci          // 4.2.6.10
6881cb0ef41Sopenharmony_ci          addedItems.push([operation.request, operation.response])
6891cb0ef41Sopenharmony_ci        }
6901cb0ef41Sopenharmony_ci
6911cb0ef41Sopenharmony_ci        // 4.2.7
6921cb0ef41Sopenharmony_ci        resultList.push([operation.request, operation.response])
6931cb0ef41Sopenharmony_ci      }
6941cb0ef41Sopenharmony_ci
6951cb0ef41Sopenharmony_ci      // 4.3
6961cb0ef41Sopenharmony_ci      return resultList
6971cb0ef41Sopenharmony_ci    } catch (e) { // 5.
6981cb0ef41Sopenharmony_ci      // 5.1
6991cb0ef41Sopenharmony_ci      this.#relevantRequestResponseList.length = 0
7001cb0ef41Sopenharmony_ci
7011cb0ef41Sopenharmony_ci      // 5.2
7021cb0ef41Sopenharmony_ci      this.#relevantRequestResponseList = backupCache
7031cb0ef41Sopenharmony_ci
7041cb0ef41Sopenharmony_ci      // 5.3
7051cb0ef41Sopenharmony_ci      throw e
7061cb0ef41Sopenharmony_ci    }
7071cb0ef41Sopenharmony_ci  }
7081cb0ef41Sopenharmony_ci
7091cb0ef41Sopenharmony_ci  /**
7101cb0ef41Sopenharmony_ci   * @see https://w3c.github.io/ServiceWorker/#query-cache
7111cb0ef41Sopenharmony_ci   * @param {any} requestQuery
7121cb0ef41Sopenharmony_ci   * @param {import('../../types/cache').CacheQueryOptions} options
7131cb0ef41Sopenharmony_ci   * @param {requestResponseList} targetStorage
7141cb0ef41Sopenharmony_ci   * @returns {requestResponseList}
7151cb0ef41Sopenharmony_ci   */
7161cb0ef41Sopenharmony_ci  #queryCache (requestQuery, options, targetStorage) {
7171cb0ef41Sopenharmony_ci    /** @type {requestResponseList} */
7181cb0ef41Sopenharmony_ci    const resultList = []
7191cb0ef41Sopenharmony_ci
7201cb0ef41Sopenharmony_ci    const storage = targetStorage ?? this.#relevantRequestResponseList
7211cb0ef41Sopenharmony_ci
7221cb0ef41Sopenharmony_ci    for (const requestResponse of storage) {
7231cb0ef41Sopenharmony_ci      const [cachedRequest, cachedResponse] = requestResponse
7241cb0ef41Sopenharmony_ci      if (this.#requestMatchesCachedItem(requestQuery, cachedRequest, cachedResponse, options)) {
7251cb0ef41Sopenharmony_ci        resultList.push(requestResponse)
7261cb0ef41Sopenharmony_ci      }
7271cb0ef41Sopenharmony_ci    }
7281cb0ef41Sopenharmony_ci
7291cb0ef41Sopenharmony_ci    return resultList
7301cb0ef41Sopenharmony_ci  }
7311cb0ef41Sopenharmony_ci
7321cb0ef41Sopenharmony_ci  /**
7331cb0ef41Sopenharmony_ci   * @see https://w3c.github.io/ServiceWorker/#request-matches-cached-item-algorithm
7341cb0ef41Sopenharmony_ci   * @param {any} requestQuery
7351cb0ef41Sopenharmony_ci   * @param {any} request
7361cb0ef41Sopenharmony_ci   * @param {any | null} response
7371cb0ef41Sopenharmony_ci   * @param {import('../../types/cache').CacheQueryOptions | undefined} options
7381cb0ef41Sopenharmony_ci   * @returns {boolean}
7391cb0ef41Sopenharmony_ci   */
7401cb0ef41Sopenharmony_ci  #requestMatchesCachedItem (requestQuery, request, response = null, options) {
7411cb0ef41Sopenharmony_ci    // if (options?.ignoreMethod === false && request.method === 'GET') {
7421cb0ef41Sopenharmony_ci    //   return false
7431cb0ef41Sopenharmony_ci    // }
7441cb0ef41Sopenharmony_ci
7451cb0ef41Sopenharmony_ci    const queryURL = new URL(requestQuery.url)
7461cb0ef41Sopenharmony_ci
7471cb0ef41Sopenharmony_ci    const cachedURL = new URL(request.url)
7481cb0ef41Sopenharmony_ci
7491cb0ef41Sopenharmony_ci    if (options?.ignoreSearch) {
7501cb0ef41Sopenharmony_ci      cachedURL.search = ''
7511cb0ef41Sopenharmony_ci
7521cb0ef41Sopenharmony_ci      queryURL.search = ''
7531cb0ef41Sopenharmony_ci    }
7541cb0ef41Sopenharmony_ci
7551cb0ef41Sopenharmony_ci    if (!urlEquals(queryURL, cachedURL, true)) {
7561cb0ef41Sopenharmony_ci      return false
7571cb0ef41Sopenharmony_ci    }
7581cb0ef41Sopenharmony_ci
7591cb0ef41Sopenharmony_ci    if (
7601cb0ef41Sopenharmony_ci      response == null ||
7611cb0ef41Sopenharmony_ci      options?.ignoreVary ||
7621cb0ef41Sopenharmony_ci      !response.headersList.contains('vary')
7631cb0ef41Sopenharmony_ci    ) {
7641cb0ef41Sopenharmony_ci      return true
7651cb0ef41Sopenharmony_ci    }
7661cb0ef41Sopenharmony_ci
7671cb0ef41Sopenharmony_ci    const fieldValues = getFieldValues(response.headersList.get('vary'))
7681cb0ef41Sopenharmony_ci
7691cb0ef41Sopenharmony_ci    for (const fieldValue of fieldValues) {
7701cb0ef41Sopenharmony_ci      if (fieldValue === '*') {
7711cb0ef41Sopenharmony_ci        return false
7721cb0ef41Sopenharmony_ci      }
7731cb0ef41Sopenharmony_ci
7741cb0ef41Sopenharmony_ci      const requestValue = request.headersList.get(fieldValue)
7751cb0ef41Sopenharmony_ci      const queryValue = requestQuery.headersList.get(fieldValue)
7761cb0ef41Sopenharmony_ci
7771cb0ef41Sopenharmony_ci      // If one has the header and the other doesn't, or one has
7781cb0ef41Sopenharmony_ci      // a different value than the other, return false
7791cb0ef41Sopenharmony_ci      if (requestValue !== queryValue) {
7801cb0ef41Sopenharmony_ci        return false
7811cb0ef41Sopenharmony_ci      }
7821cb0ef41Sopenharmony_ci    }
7831cb0ef41Sopenharmony_ci
7841cb0ef41Sopenharmony_ci    return true
7851cb0ef41Sopenharmony_ci  }
7861cb0ef41Sopenharmony_ci}
7871cb0ef41Sopenharmony_ci
7881cb0ef41Sopenharmony_ciObject.defineProperties(Cache.prototype, {
7891cb0ef41Sopenharmony_ci  [Symbol.toStringTag]: {
7901cb0ef41Sopenharmony_ci    value: 'Cache',
7911cb0ef41Sopenharmony_ci    configurable: true
7921cb0ef41Sopenharmony_ci  },
7931cb0ef41Sopenharmony_ci  match: kEnumerableProperty,
7941cb0ef41Sopenharmony_ci  matchAll: kEnumerableProperty,
7951cb0ef41Sopenharmony_ci  add: kEnumerableProperty,
7961cb0ef41Sopenharmony_ci  addAll: kEnumerableProperty,
7971cb0ef41Sopenharmony_ci  put: kEnumerableProperty,
7981cb0ef41Sopenharmony_ci  delete: kEnumerableProperty,
7991cb0ef41Sopenharmony_ci  keys: kEnumerableProperty
8001cb0ef41Sopenharmony_ci})
8011cb0ef41Sopenharmony_ci
8021cb0ef41Sopenharmony_ciconst cacheQueryOptionConverters = [
8031cb0ef41Sopenharmony_ci  {
8041cb0ef41Sopenharmony_ci    key: 'ignoreSearch',
8051cb0ef41Sopenharmony_ci    converter: webidl.converters.boolean,
8061cb0ef41Sopenharmony_ci    defaultValue: false
8071cb0ef41Sopenharmony_ci  },
8081cb0ef41Sopenharmony_ci  {
8091cb0ef41Sopenharmony_ci    key: 'ignoreMethod',
8101cb0ef41Sopenharmony_ci    converter: webidl.converters.boolean,
8111cb0ef41Sopenharmony_ci    defaultValue: false
8121cb0ef41Sopenharmony_ci  },
8131cb0ef41Sopenharmony_ci  {
8141cb0ef41Sopenharmony_ci    key: 'ignoreVary',
8151cb0ef41Sopenharmony_ci    converter: webidl.converters.boolean,
8161cb0ef41Sopenharmony_ci    defaultValue: false
8171cb0ef41Sopenharmony_ci  }
8181cb0ef41Sopenharmony_ci]
8191cb0ef41Sopenharmony_ci
8201cb0ef41Sopenharmony_ciwebidl.converters.CacheQueryOptions = webidl.dictionaryConverter(cacheQueryOptionConverters)
8211cb0ef41Sopenharmony_ci
8221cb0ef41Sopenharmony_ciwebidl.converters.MultiCacheQueryOptions = webidl.dictionaryConverter([
8231cb0ef41Sopenharmony_ci  ...cacheQueryOptionConverters,
8241cb0ef41Sopenharmony_ci  {
8251cb0ef41Sopenharmony_ci    key: 'cacheName',
8261cb0ef41Sopenharmony_ci    converter: webidl.converters.DOMString
8271cb0ef41Sopenharmony_ci  }
8281cb0ef41Sopenharmony_ci])
8291cb0ef41Sopenharmony_ci
8301cb0ef41Sopenharmony_ciwebidl.converters.Response = webidl.interfaceConverter(Response)
8311cb0ef41Sopenharmony_ci
8321cb0ef41Sopenharmony_ciwebidl.converters['sequence<RequestInfo>'] = webidl.sequenceConverter(
8331cb0ef41Sopenharmony_ci  webidl.converters.RequestInfo
8341cb0ef41Sopenharmony_ci)
8351cb0ef41Sopenharmony_ci
8361cb0ef41Sopenharmony_cimodule.exports = {
8371cb0ef41Sopenharmony_ci  Cache
8381cb0ef41Sopenharmony_ci}
839