- Delete old Vite+Svelte frontend - Initialize new SvelteKit project with TypeScript - Configure Tailwind CSS v4 + DaisyUI - Implement JWT authentication with auto-refresh - Create login page with form validation (Zod) - Add protected route guards - Update Docker configuration for single-stage build - Add E2E tests with Playwright (6/11 passing) - Fix Svelte 5 reactivity with $state() runes Known issues: - 5 E2E tests failing (timing/async issues) - Token refresh implementation needs debugging - Validation error display timing
41 lines
1.2 KiB
JavaScript
41 lines
1.2 KiB
JavaScript
/*
|
|
Deep clones all properties except functions
|
|
|
|
var arr = [1, 2, 3];
|
|
var subObj = {aa: 1};
|
|
var obj = {a: 3, b: 5, c: arr, d: subObj};
|
|
var objClone = clone(obj);
|
|
arr.push(4);
|
|
subObj.bb = 2;
|
|
obj; // {a: 3, b: 5, c: [1, 2, 3, 4], d: {aa: 1}}
|
|
objClone; // {a: 3, b: 5, c: [1, 2, 3], d: {aa: 1, bb: 2}}
|
|
*/
|
|
export function clone(obj) {
|
|
const type = {}.toString.call(obj).slice(8, -1);
|
|
if (type == 'Set') {
|
|
// @ts-expect-error Known type
|
|
return new Set([...obj].map((value) => clone(value)));
|
|
}
|
|
if (type == 'Map') {
|
|
// @ts-expect-error Known type
|
|
return new Map([...obj].map((kv) => [clone(kv[0]), clone(kv[1])]));
|
|
}
|
|
if (type == 'Date') {
|
|
// @ts-expect-error Known type
|
|
return new Date(obj.getTime());
|
|
}
|
|
if (type == 'RegExp') {
|
|
// @ts-expect-error Known type
|
|
return RegExp(obj.source, obj.flags);
|
|
}
|
|
if (type == 'Array' || type == 'Object') {
|
|
const result = type == 'Object' ? Object.create(Object.getPrototypeOf(obj)) : [];
|
|
for (const key in obj) {
|
|
result[key] = clone(obj[key]);
|
|
}
|
|
return result;
|
|
}
|
|
// primitives and non-supported objects (e.g. functions) land here
|
|
return obj;
|
|
}
|