mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-27 09:21:35 +07:00
refactor: share config path traversal helper
This commit is contained in:
@@ -15,49 +15,75 @@ function isForbiddenKey(key: string | number): boolean {
|
||||
return typeof key === "string" && FORBIDDEN_KEYS.has(key);
|
||||
}
|
||||
|
||||
export function setPathValue(
|
||||
type PathContainer = {
|
||||
current: Record<string, unknown> | unknown[];
|
||||
lastKey: string | number;
|
||||
};
|
||||
|
||||
function resolvePathContainer(
|
||||
obj: Record<string, unknown> | unknown[],
|
||||
path: Array<string | number>,
|
||||
value: unknown,
|
||||
) {
|
||||
if (path.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (path.some(isForbiddenKey)) {
|
||||
return;
|
||||
createMissing: boolean,
|
||||
): PathContainer | null {
|
||||
if (path.length === 0 || path.some(isForbiddenKey)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let current: Record<string, unknown> | unknown[] = obj;
|
||||
for (let i = 0; i < path.length - 1; i += 1) {
|
||||
const key = path[i];
|
||||
const nextKey = path[i + 1];
|
||||
if (typeof key === "number") {
|
||||
if (!Array.isArray(current)) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
if (current[key] == null) {
|
||||
if (!createMissing) {
|
||||
return null;
|
||||
}
|
||||
current[key] = typeof nextKey === "number" ? [] : ({} as Record<string, unknown>);
|
||||
}
|
||||
current = current[key] as Record<string, unknown> | unknown[];
|
||||
} else {
|
||||
if (typeof current !== "object" || current == null) {
|
||||
return;
|
||||
}
|
||||
const record = current as Record<string, unknown>;
|
||||
if (record[key] == null) {
|
||||
record[key] = typeof nextKey === "number" ? [] : ({} as Record<string, unknown>);
|
||||
}
|
||||
current = record[key] as Record<string, unknown> | unknown[];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof current !== "object" || current == null) {
|
||||
return null;
|
||||
}
|
||||
const record = current as Record<string, unknown>;
|
||||
if (record[key] == null) {
|
||||
if (!createMissing) {
|
||||
return null;
|
||||
}
|
||||
record[key] = typeof nextKey === "number" ? [] : ({} as Record<string, unknown>);
|
||||
}
|
||||
current = record[key] as Record<string, unknown> | unknown[];
|
||||
}
|
||||
const lastKey = path[path.length - 1];
|
||||
if (typeof lastKey === "number") {
|
||||
if (Array.isArray(current)) {
|
||||
current[lastKey] = value;
|
||||
|
||||
return {
|
||||
current,
|
||||
lastKey: path[path.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
export function setPathValue(
|
||||
obj: Record<string, unknown> | unknown[],
|
||||
path: Array<string | number>,
|
||||
value: unknown,
|
||||
) {
|
||||
const container = resolvePathContainer(obj, path, true);
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof container.lastKey === "number") {
|
||||
if (Array.isArray(container.current)) {
|
||||
container.current[container.lastKey] = value;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (typeof current === "object" && current != null) {
|
||||
(current as Record<string, unknown>)[lastKey] = value;
|
||||
if (typeof container.current === "object" && container.current != null) {
|
||||
(container.current as Record<string, unknown>)[container.lastKey] = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,38 +91,18 @@ export function removePathValue(
|
||||
obj: Record<string, unknown> | unknown[],
|
||||
path: Array<string | number>,
|
||||
) {
|
||||
if (path.length === 0) {
|
||||
const container = resolvePathContainer(obj, path, false);
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
if (path.some(isForbiddenKey)) {
|
||||
return;
|
||||
}
|
||||
let current: Record<string, unknown> | unknown[] = obj;
|
||||
for (let i = 0; i < path.length - 1; i += 1) {
|
||||
const key = path[i];
|
||||
if (typeof key === "number") {
|
||||
if (!Array.isArray(current)) {
|
||||
return;
|
||||
}
|
||||
current = current[key] as Record<string, unknown> | unknown[];
|
||||
} else {
|
||||
if (typeof current !== "object" || current == null) {
|
||||
return;
|
||||
}
|
||||
current = (current as Record<string, unknown>)[key] as Record<string, unknown> | unknown[];
|
||||
}
|
||||
if (current == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const lastKey = path[path.length - 1];
|
||||
if (typeof lastKey === "number") {
|
||||
if (Array.isArray(current)) {
|
||||
current.splice(lastKey, 1);
|
||||
|
||||
if (typeof container.lastKey === "number") {
|
||||
if (Array.isArray(container.current)) {
|
||||
container.current.splice(container.lastKey, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (typeof current === "object" && current != null) {
|
||||
delete (current as Record<string, unknown>)[lastKey];
|
||||
if (typeof container.current === "object" && container.current != null) {
|
||||
delete (container.current as Record<string, unknown>)[container.lastKey];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user