All files / lib/internal/modules/esm load.js

94.23% Statements 98/104
93.33% Branches 28/30
100% Functions 2/2
94.23% Lines 98/104

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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 145x 687x 687x 687x 687x 687x 592x 681x 35x 35x 1x 1x 34x 35x 95x 60x 30x 60x 60x 60x 60x 60x             687x 3x 3x 686x 687x 145x 145x 145x 145x 145x 145x 145x 145x 1196x 1196x 1196x 1196x 1196x 1196x 1196x 1196x 1196x 187x 166x 1175x 1175x 1175x 1175x 1188x 800x 1196x 475x 1116x 687x 686x 1161x 1161x 1161x 1161x 1161x 1161x 1196x 145x 145x 145x 145x  
'use strict';
 
const {
  ArrayPrototypePush,
  RegExpPrototypeExec,
  decodeURIComponent,
} = primordials;
 
const { defaultGetFormat } = require('internal/modules/esm/get_format');
const { validateAssertions } = require('internal/modules/esm/assert');
const { getOptionValue } = require('internal/options');
const { fetchModule } = require('internal/modules/esm/fetch_module');
 
// Do not eagerly grab .manifest, it may be in TDZ
const policy = getOptionValue('--experimental-policy') ?
  require('internal/process/policy') :
  null;
const experimentalNetworkImports =
  getOptionValue('--experimental-network-imports');
 
const { Buffer: { from: BufferFrom } } = require('buffer');
 
const { readFile: readFileAsync } = require('internal/fs/promises').exports;
const { URL } = require('internal/url');
const {
  ERR_INVALID_URL,
  ERR_UNSUPPORTED_ESM_URL_SCHEME,
} = require('internal/errors').codes;
 
const DATA_URL_PATTERN = /^[^/]+\/[^,;]+(?:[^,]*?)(;base64)?,([\s\S]*)$/;
 
async function getSource(url, context) {
  const parsed = new URL(url);
  let responseURL = url;
  let source;
  if (parsed.protocol === 'file:') {
    source = await readFileAsync(parsed);
  } else if (parsed.protocol === 'data:') {
    const match = RegExpPrototypeExec(DATA_URL_PATTERN, parsed.pathname);
    if (!match) {
      throw new ERR_INVALID_URL(url);
    }
    const { 1: base64, 2: body } = match;
    source = BufferFrom(decodeURIComponent(body), base64 ? 'base64' : 'utf8');
  } else if (experimentalNetworkImports && (
    parsed.protocol === 'https:' ||
    parsed.protocol === 'http:'
  )) {
    const res = await fetchModule(parsed, context);
    source = await res.body;
    responseURL = res.resolvedHREF;
  } else {
    const supportedSchemes = ['file', 'data'];
    if (experimentalNetworkImports) {
      ArrayPrototypePush(supportedSchemes, 'http', 'https');
    }
    throw new ERR_UNSUPPORTED_ESM_URL_SCHEME(parsed, supportedSchemes);
  }
  if (policy?.manifest) {
    policy.manifest.assertIntegrity(parsed, source);
  }
  return { responseURL, source };
}
 
 
/**
 * Node.js default load hook.
 * @param {string} url
 * @param {object} context
 * @returns {object}
 */
async function defaultLoad(url, context) {
  let responseURL = url;
  const { importAssertions } = context;
  let {
    format,
    source,
  } = context;
 
  if (format == null) {
    format = await defaultGetFormat(url, context);
  }
 
  validateAssertions(url, format, importAssertions);
 
  if (
    format === 'builtin' ||
    format === 'commonjs'
  ) {
    source = null;
  } else if (source == null) {
    ({ responseURL, source } = await getSource(url, context));
  }
 
  return {
    format,
    responseURL,
    source,
  };
}
 
module.exports = {
  defaultLoad,
};