Repository: dotnet/runtime
File: src/native/libs/Common/JavaScript/loader/config.ts (TypeScript)

Code before:
}

function mergeResources(target: Assets, source: Assets): Assets {
    // no need to merge the same object
    if (target === source || source === undefined || source === null) return target;

    source.coreAssembly = [...target.coreAssembly!, ...source.coreAssembly!];
    source.assembly = [...target.assembly!, ...source.assembly!];
    source.lazyAssembly = [...target.lazyAssembly!, ...source.lazyAssembly!];
    source.corePdb = [...target.corePdb!, ...source.corePdb!];
    source.pdb = [...target.pdb!, ...source.pdb!];
    source.jsModuleWorker = [...target.jsModuleWorker!, ...source.jsModuleWorker!];
    source.jsModuleNative = [...target.jsModuleNative!, ...source.jsModuleNative!];
    source.jsModuleDiagnostics = [...target.jsModuleDiagnostics!, ...source.jsModuleDiagnostics!];
    source.jsModuleRuntime = [...target.jsModuleRuntime!, ...source.jsModuleRuntime!];
    source.wasmSymbols = [...target.wasmSymbols!, ...source.wasmSymbols!];
    source.wasmNative = [...target.wasmNative!, ...source.wasmNative!];
    source.icu = [...target.icu!, ...source.icu!];
    source.vfs = [...target.vfs!, ...source.vfs!];
    source.modulesAfterConfigLoaded = [...target.modulesAfterConfigLoaded!, ...source.modulesAfterConfigLoaded!];
    source.modulesAfterRuntimeReady = [...target.modulesAfterRuntimeReady!, ...source.modulesAfterRuntimeReady!];
    source.extensions = { ...target.extensions!, ...source.extensions! };
    for (const key in source.satelliteResources) {
        source.satelliteResources![key] = [...target.satelliteResources![key] || [], ...source.satelliteResources![key] || []];
    }
    for (const key in target.satelliteResources) {
        source.satelliteResources![key] = [...target.satelliteResources![key] || [], ...source.satelliteResources![key] || []];
    }
    return Object.assign(target, source);
}

function defaultConfig(target: LoaderConfigInternal) {
    if (target.appendElementOnExit === undefined) target.appendElementOnExit = false;
    if (target.logExitCode === undefined) target.logExitCode = false;
    if (target.exitOnUnhandledError === undefined) target.exitOnUnhandledError = false;
    if (target.loadAllSatelliteResources === undefined) target.loadAllSatelliteResources = false;
    if (target.debugLevel === undefined) target.debugLevel = 0;
    if (target.diagnosticTracing === undefined) target.diagnosticTracing = false;
    if (target.virtualWorkingDirectory === undefined) target.virtualWorkingDirectory = browserVirtualAppBase;
    if (target.maxParallelDownloads === undefined) target.maxParallelDownloads = 16;
    normalizeConfig(target);
}

function normalizeConfig(target: LoaderConfigInternal) {
    if (!target.resources) target.resources = {} as any;
    normalizeResources(target.resources!);
    if (!target.environmentVariables) target.environmentVariables = {};
    if (!target.runtimeOptions) target.runtimeOptions = [];
    if (!target.runtimeConfig) {
        target.runtimeConfig = { runtimeOptions: { configProperties: {} }, };
    } else if (!target.runtimeConfig.runtimeOptions) {

Review comment (refactor):
If we have culture in both source and target, that will duplicate the entries. We should defend against it, e.g.
```
for (const key in target.satelliteResources) {
    if (!Object.prototype.hasOwnProperty.call(source.satelliteResources, key)) {
        source.satelliteResources![key] = target.satelliteResources![key] || [];
    }
}
```

Code after:
}

function mergeResources(target: Assets, source: Assets): Assets {
    // no need to merge the same object
    if (target === source || source === undefined || source === null) return target;

    source.coreAssembly = [...target.coreAssembly!, ...source.coreAssembly!];
    source.assembly = [...target.assembly!, ...source.assembly!];
    source.lazyAssembly = [...target.lazyAssembly!, ...source.lazyAssembly!];
    source.corePdb = [...target.corePdb!, ...source.corePdb!];
    source.pdb = [...target.pdb!, ...source.pdb!];
    source.jsModuleWorker = [...target.jsModuleWorker!, ...source.jsModuleWorker!];
    source.jsModuleNative = [...target.jsModuleNative!, ...source.jsModuleNative!];
    source.jsModuleDiagnostics = [...target.jsModuleDiagnostics!, ...source.jsModuleDiagnostics!];
    source.jsModuleRuntime = [...target.jsModuleRuntime!, ...source.jsModuleRuntime!];
    source.wasmSymbols = [...target.wasmSymbols!, ...source.wasmSymbols!];
    source.wasmNative = [...target.wasmNative!, ...source.wasmNative!];
    source.icu = [...target.icu!, ...source.icu!];
    source.vfs = [...target.vfs!, ...source.vfs!];
    source.modulesAfterConfigLoaded = [...target.modulesAfterConfigLoaded!, ...source.modulesAfterConfigLoaded!];
    source.modulesAfterRuntimeReady = [...target.modulesAfterRuntimeReady!, ...source.modulesAfterRuntimeReady!];
    source.extensions = { ...target.extensions!, ...source.extensions! };
    for (const key in source.satelliteResources) {
        source.satelliteResources![key] = [...target.satelliteResources![key] || [], ...source.satelliteResources![key] || []];
    }
    for (const key in target.satelliteResources) {
        if (!Object.prototype.hasOwnProperty.call(source.satelliteResources, key)) {
            source.satelliteResources![key] = target.satelliteResources![key] || [];
        }
    }
    return Object.assign(target, source);
}

function defaultConfig(target: LoaderConfigInternal) {
    if (target.appendElementOnExit === undefined) target.appendElementOnExit = false;
    if (target.logExitCode === undefined) target.logExitCode = false;
    if (target.exitOnUnhandledError === undefined) target.exitOnUnhandledError = false;
    if (target.loadAllSatelliteResources === undefined) target.loadAllSatelliteResources = false;
    if (target.debugLevel === undefined) target.debugLevel = 0;
    if (target.diagnosticTracing === undefined) target.diagnosticTracing = false;
    if (target.virtualWorkingDirectory === undefined) target.virtualWorkingDirectory = browserVirtualAppBase;
    if (target.maxParallelDownloads === undefined) target.maxParallelDownloads = 16;
    normalizeConfig(target);
}

function normalizeConfig(target: LoaderConfigInternal) {
    if (!target.resources) target.resources = {} as any;
    normalizeResources(target.resources!);
    if (!target.environmentVariables) target.environmentVariables = {};
    if (!target.runtimeOptions) target.runtimeOptions = [];
    if (!target.runtimeConfig) {