Repository: dotnet/runtime
File: src/mono/browser/runtime/loader/polyfills.ts (TypeScript)

Code before:
};

export function verifyEnvironment () {
    mono_assert(ENVIRONMENT_IS_SHELL || typeof globalThis.URL === "function", "This browser/engine doesn't support URL API. Please use a modern version. See also https://learn.microsoft.com/en-us/aspnet/core/blazor/supported-platforms");
    mono_assert(typeof globalThis.BigInt64Array === "function", "This browser/engine doesn't support BigInt64Array API. Please use a modern version. See also https://learn.microsoft.com/en-us/aspnet/core/blazor/supported-platforms");
    mono_assert(globalThis.performance && typeof globalThis.performance.now === "function", "This browser/engine doesn't support performance.now. Please use a modern version.");
    mono_assert(ENVIRONMENT_IS_SHELL || globalThis.crypto && typeof globalThis.crypto.subtle === "object", "This engine doesn't support crypto.subtle. Please use a modern version.");
    mono_assert(ENVIRONMENT_IS_SHELL || globalThis.crypto && typeof globalThis.crypto.getRandomValues === "function", "This engine doesn't support crypto.getRandomValues. Please use a modern version.");
    if (ENVIRONMENT_IS_NODE) {
        mono_assert(typeof process.exit === "function", "This engine doesn't support process.exit. Please use a modern version.");
    }
    if (WasmEnableThreads) {
        mono_assert(!ENVIRONMENT_IS_SHELL && !ENVIRONMENT_IS_NODE, "This build of dotnet is multi-threaded, it doesn't support shell environments like V8 or NodeJS. See also https://learn.microsoft.com/en-us/aspnet/core/blazor/supported-platforms");
        mono_assert(globalThis.SharedArrayBuffer !== undefined, "SharedArrayBuffer is not enabled on this page. Please use a modern browser and set Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy http headers. See also https://learn.microsoft.com/en-us/aspnet/core/blazor/supported-platforms");
        mono_assert(typeof globalThis.EventTarget === "function", "This browser/engine doesn't support EventTarget API. Please use a modern version. See also https://learn.microsoft.com/en-us/aspnet/core/blazor/supported-platforms");
    }
}

export async function detect_features_and_polyfill (module: DotnetModuleInternal): Promise<void> {
    if (ENVIRONMENT_IS_NODE) {
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-ignore:
        const process = await import(/*! webpackIgnore: true */"process");
        const minNodeVersion = 14;
        if (process.versions.node.split(".")[0] < minNodeVersion) {
            throw new Error(`NodeJS at '${process.execPath}' has too low version '${process.versions.node}', please use at least ${minNodeVersion}. See also https://learn.microsoft.com/en-us/aspnet/core/blazor/supported-platforms`);
        }
    }

    const scriptUrlQuery = /*! webpackIgnore: true */import.meta.url;
    const queryIndex = scriptUrlQuery.indexOf("?");
    if (queryIndex > 0) {
        loaderHelpers.modulesUniqueQuery = scriptUrlQuery.substring(queryIndex);
    }
    loaderHelpers.scriptUrl = normalizeFileUrl(scriptUrlQuery);
    loaderHelpers.scriptDirectory = normalizeDirectoryUrl(loaderHelpers.scriptUrl);
    loaderHelpers.locateFile = (path) => {
        if ("URL" in globalThis && globalThis.URL !== (URLPolyfill as any)) {
            return new URL(path, loaderHelpers.scriptDirectory).toString();
        }

        if (isPathAbsolute(path)) return path;
        return loaderHelpers.scriptDirectory + path;
    };
    loaderHelpers.fetch_like = fetch_like;
    // eslint-disable-next-line no-console
    loaderHelpers.out = console.log;
    // eslint-disable-next-line no-console
    loaderHelpers.err = console.error;
    loaderHelpers.onDownloadResourceProgress = module.onDownloadResourceProgress;


Review comment (suggestion):
```suggestion
            throw new Error(`NodeJS at '${process.execPath}' has too low version '${process.versions.node}', please use at least ${minNodeVersion}.`);
```

Code after:
};

export function verifyEnvironment () {
    mono_assert(ENVIRONMENT_IS_SHELL || typeof globalThis.URL === "function", "This browser/engine doesn't support URL API. Please use a modern version.");
    mono_assert(typeof globalThis.BigInt64Array === "function", "This browser/engine doesn't support BigInt64Array API. Please use a modern version. See also https://learn.microsoft.com/aspnet/core/blazor/supported-platforms");
    mono_assert(globalThis.performance && typeof globalThis.performance.now === "function", "This browser/engine doesn't support performance.now. Please use a modern version.");
    mono_assert(ENVIRONMENT_IS_SHELL || globalThis.crypto && typeof globalThis.crypto.subtle === "object", "This engine doesn't support crypto.subtle. Please use a modern version.");
    mono_assert(ENVIRONMENT_IS_SHELL || globalThis.crypto && typeof globalThis.crypto.getRandomValues === "function", "This engine doesn't support crypto.getRandomValues. Please use a modern version.");
    if (ENVIRONMENT_IS_NODE) {
        mono_assert(typeof process.exit === "function", "This engine doesn't support process.exit. Please use a modern version.");
    }
    if (WasmEnableThreads) {
        mono_assert(!ENVIRONMENT_IS_SHELL && !ENVIRONMENT_IS_NODE, "This build of dotnet is multi-threaded, it doesn't support shell environments like V8 or NodeJS.");
        mono_assert(globalThis.SharedArrayBuffer !== undefined, "SharedArrayBuffer is not enabled on this page. Please use a modern browser and set Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy http headers.");
        mono_assert(typeof globalThis.EventTarget === "function", "This browser/engine doesn't support EventTarget API. Please use a modern version. See also https://learn.microsoft.com/aspnet/core/blazor/supported-platforms");
    }
}

export async function detect_features_and_polyfill (module: DotnetModuleInternal): Promise<void> {
    if (ENVIRONMENT_IS_NODE) {
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-ignore:
        const process = await import(/*! webpackIgnore: true */"process");
        const minNodeVersion = 14;
        if (process.versions.node.split(".")[0] < minNodeVersion) {
            throw new Error(`NodeJS at '${process.execPath}' has too low version '${process.versions.node}', please use at least ${minNodeVersion}.`);
        }
    }

    const scriptUrlQuery = /*! webpackIgnore: true */import.meta.url;
    const queryIndex = scriptUrlQuery.indexOf("?");
    if (queryIndex > 0) {
        loaderHelpers.modulesUniqueQuery = scriptUrlQuery.substring(queryIndex);
    }
    loaderHelpers.scriptUrl = normalizeFileUrl(scriptUrlQuery);
    loaderHelpers.scriptDirectory = normalizeDirectoryUrl(loaderHelpers.scriptUrl);
    loaderHelpers.locateFile = (path) => {
        if ("URL" in globalThis && globalThis.URL !== (URLPolyfill as any)) {
            return new URL(path, loaderHelpers.scriptDirectory).toString();
        }

        if (isPathAbsolute(path)) return path;
        return loaderHelpers.scriptDirectory + path;
    };
    loaderHelpers.fetch_like = fetch_like;
    // eslint-disable-next-line no-console
    loaderHelpers.out = console.log;
    // eslint-disable-next-line no-console
    loaderHelpers.err = console.error;
    loaderHelpers.onDownloadResourceProgress = module.onDownloadResourceProgress;