All files / kernel-platforms/src/capabilities/fetch shared.ts

100% Statements 17/17
100% Branches 7/7
100% Functions 6/6
100% Lines 17/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60                5x   22x               5x 23x 19x   19x 4x   15x 5x                     5x 19x 19x                   5x       19x 13x 11x 11x      
import type { FetchCapability, FetchCaveat, FetchConfig } from './types.ts';
 
/**
 * Cross-platform URL resolution utility
 *
 * @param arg - The input to resolve
 * @returns The resolved URL
 */
export const resolveUrl = (arg: Parameters<typeof fetch>[0]): URL =>
  // eslint-disable-next-line n/no-unsupported-features/node-builtins
  new URL(arg instanceof Request ? arg.url : arg);
 
/**
 * Cross-platform host caveat factory
 *
 * @param allowedHosts - The allowed hosts
 * @returns A caveat that restricts the fetch to only the allowed hosts
 */
export const makeHostCaveat = (allowedHosts: string[]): FetchCaveat => {
  return harden(async (...args: Parameters<typeof fetch>) => {
    const { host, protocol } = resolveUrl(args[0]);
    // Allow file:// URLs to pass through
    if (protocol === 'file:') {
      return;
    }
    if (!allowedHosts.includes(host)) {
      throw new Error(`Invalid host: ${host}`);
    }
  });
};
 
/**
 * Cross-platform fetch caveat factory
 *
 * @param config - The configuration for the fetch caveat
 * @returns A caveat that restricts a fetch capability according to the specified configuration
 */
export const makeFetchCaveat = (config: FetchConfig): FetchCaveat => {
  const { allowedHosts = [] } = config;
  return makeHostCaveat(allowedHosts);
};
 
/**
 * Cross-platform fetch caveat wrapper
 *
 * @param baseFetch - The underlying fetch capability to wrap
 * @param caveat - The caveat to apply to the fetch capability
 * @returns A fetch capability restricted by the provided caveat
 */
export const makeCaveatedFetch = (
  baseFetch: FetchCapability,
  caveat: FetchCaveat,
): FetchCapability => {
  return harden(async (...args: Parameters<FetchCapability>) => {
    await caveat(...args);
    const response = await baseFetch(...args);
    return response;
  });
};