2021-06-28 04:04:48 +02:00
|
|
|
import { assert } from "tsafe/assert";
|
|
|
|
import { is } from "tsafe/is";
|
2024-06-02 00:24:07 +02:00
|
|
|
import { structuredCloneButFunctions } from "./structuredCloneButFunctions";
|
2021-11-07 20:17:14 +01:00
|
|
|
|
2024-06-03 18:28:34 +02:00
|
|
|
/** NOTE: Array a copied over, not merged. */
|
2024-05-20 15:48:51 +02:00
|
|
|
export function deepAssign(params: {
|
|
|
|
target: Record<string, unknown>;
|
|
|
|
source: Record<string, unknown>;
|
2024-06-03 18:28:34 +02:00
|
|
|
}): void {
|
|
|
|
const { target, source } = params;
|
2021-10-11 21:35:40 +02:00
|
|
|
|
|
|
|
Object.keys(source).forEach(key => {
|
|
|
|
var dereferencedSource = source[key];
|
|
|
|
|
2024-06-03 18:28:34 +02:00
|
|
|
if (dereferencedSource === undefined) {
|
|
|
|
delete target[key];
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dereferencedSource instanceof Date) {
|
|
|
|
assign({
|
|
|
|
target,
|
|
|
|
key,
|
|
|
|
value: new Date(dereferencedSource.getTime())
|
|
|
|
});
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dereferencedSource instanceof Array) {
|
|
|
|
assign({
|
|
|
|
target,
|
|
|
|
key,
|
|
|
|
value: structuredCloneButFunctions(dereferencedSource)
|
|
|
|
});
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-05-20 15:48:51 +02:00
|
|
|
if (
|
|
|
|
dereferencedSource instanceof Function ||
|
|
|
|
!(dereferencedSource instanceof Object)
|
|
|
|
) {
|
2024-06-03 18:28:34 +02:00
|
|
|
assign({
|
|
|
|
target,
|
|
|
|
key,
|
2024-05-20 15:48:51 +02:00
|
|
|
value: dereferencedSource
|
2021-10-11 21:35:40 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-06-03 18:28:34 +02:00
|
|
|
if (!(target[key] instanceof Object)) {
|
|
|
|
target[key] = {};
|
2021-10-11 21:35:40 +02:00
|
|
|
}
|
|
|
|
|
2024-06-03 18:28:34 +02:00
|
|
|
const dereferencedTarget = target[key];
|
|
|
|
|
2021-10-11 21:35:40 +02:00
|
|
|
assert(is<Record<string, unknown>>(dereferencedTarget));
|
|
|
|
assert(is<Record<string, unknown>>(dereferencedSource));
|
|
|
|
|
|
|
|
deepAssign({
|
2024-05-20 15:48:51 +02:00
|
|
|
target: dereferencedTarget,
|
|
|
|
source: dereferencedSource
|
2021-10-11 21:35:40 +02:00
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
2024-06-03 18:28:34 +02:00
|
|
|
|
|
|
|
function assign(params: {
|
|
|
|
target: Record<string, unknown>;
|
|
|
|
key: string;
|
|
|
|
value: unknown;
|
|
|
|
}): void {
|
|
|
|
const { target, key, value } = params;
|
|
|
|
|
|
|
|
Object.defineProperty(target, key, {
|
|
|
|
enumerable: true,
|
|
|
|
writable: true,
|
|
|
|
configurable: true,
|
|
|
|
value
|
|
|
|
});
|
|
|
|
}
|