1/**
2 * Copyright © 2022 650 Industries.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7// Basically `__webpack_require__.l`.
8export function fetchThenEvalAsync(
9  url: string,
10  {
11    scriptType,
12    nonce,
13    crossOrigin,
14  }: { scriptType?: string; nonce?: string; crossOrigin?: string } = {}
15): Promise<void> {
16  if (typeof document === 'undefined') {
17    throw new Error('Cannot use fetchThenEvalAsync in a non-browser environment.');
18  }
19  return new Promise<void>((resolve, reject) => {
20    const script = document.createElement('script');
21    if (scriptType) script.type = scriptType;
22    if (nonce) script.setAttribute('nonce', nonce);
23    // script.setAttribute('data-expo-metro', ...);
24    script.src = url;
25
26    if (crossOrigin && script.src.indexOf(window.location.origin + '/') !== 0) {
27      script.crossOrigin = crossOrigin;
28    }
29
30    script.onload = () => {
31      script.parentNode && script.parentNode.removeChild(script);
32      resolve();
33    };
34    // Create a new error object to preserve the original stack trace.
35    const error = new AsyncRequireError();
36
37    // Server error or network error.
38    script.onerror = (ev) => {
39      let event: Event;
40      if (typeof ev === 'string') {
41        event = {
42          type: 'error',
43          target: {
44            // @ts-expect-error
45            src: event,
46          },
47        };
48      } else {
49        event = ev;
50      }
51
52      const errorType = event && (event.type === 'load' ? 'missing' : event.type);
53      // @ts-expect-error
54      const realSrc = event?.target?.src;
55      error.message = 'Loading module ' + url + ' failed.\n(' + errorType + ': ' + realSrc + ')';
56      error.type = errorType;
57      error.request = realSrc;
58
59      script.parentNode && script.parentNode.removeChild(script);
60      reject(error);
61    };
62    document.head.appendChild(script);
63  });
64}
65
66class AsyncRequireError extends Error {
67  readonly name = 'AsyncRequireError';
68  type?: string;
69  request?: string;
70}
71