Repository: Significant-Gravitas/Auto-GPT
File: autogpt_platform/frontend/src/lib/utils.ts (TypeScript)

Code before:
}

export function setNestedProperty(obj: any, path: string, value: any) {
  const keys = path.split(/[\/.]/); // Split by / or .
  let current = obj;

  for (let i = 0; i < keys.length - 1; i++) {
    const key = keys[i];
    if (!current[key] || typeof current[key] !== "object") {
      current[key] = {};
    }
    current = current[key];
  }

  current[keys[keys.length - 1]] = value;
}

export function removeEmptyStringsAndNulls(obj: any): any {
  if (Array.isArray(obj)) {
    // If obj is an array, recursively remove empty strings and nulls from its elements
    return obj
      .map((item) => removeEmptyStringsAndNulls(item))
      .filter(
        (item) =>
          item !== null && (typeof item !== "string" || item.trim() !== ""),
      );
  } else if (typeof obj === "object" && obj !== null) {
    // If obj is an object, recursively remove empty strings and nulls from its properties
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        const value = obj[key];
        if (
          value === null ||
          (typeof value === "string" && value.trim() === "")
        ) {
          delete obj[key];
        } else {
          obj[key] = removeEmptyStringsAndNulls(value);
        }
      }
    }
  }
  return obj;
}

export const categoryColorMap: Record<string, string> = {
  AI: "bg-orange-300/[.7]",
  SOCIAL: "bg-yellow-300/[.7]",
  TEXT: "bg-green-300/[.7]",
  SEARCH: "bg-blue-300/[.7]",
  BASIC: "bg-purple-300/[.7]",

Review comment (bug):
I suspect [validation](https://github.com/Significant-Gravitas/AutoGPT/blob/ef7cfbb8602385685e375f6a7740af223184683a/autogpt_platform/frontend/src/hooks/useAgentGraph.ts#L344) will fail if array elements are complex objects especially with required fields. For example:
```ts
type Element = { value: number } // let's assume `value` is required in schema
input: Element[] = [
  { value: 3 }, // this is good
  null,         // this is ok because `null` isn't of type element but can also introduce validation errors
  ""            // uh oh, expected element with compulsory `value` has `string`
]
```
However I couldn't find any concrete block like this and PR works with what I tested (`List Iterator`).

Code after:
}

export function setNestedProperty(obj: any, path: string, value: any) {
  const keys = path.split(/[\/.]/); // Split by / or .
  let current = obj;

  for (let i = 0; i < keys.length - 1; i++) {
    const key = keys[i];
    if (!current[key] || typeof current[key] !== "object") {
      current[key] = {};
    }
    current = current[key];
  }

  current[keys[keys.length - 1]] = value;
}

export function removeEmptyStringsAndNulls(obj: any): any {
  if (Array.isArray(obj)) {
    // If obj is an array, recursively check each element,
    // but element removal is avoided to prevent index changes.
    return obj.map((item) =>
      item === undefined || item === null
        ? ""
        : removeEmptyStringsAndNulls(item),
    );
  } else if (typeof obj === "object" && obj !== null) {
    // If obj is an object, recursively remove empty strings and nulls from its properties
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        const value = obj[key];
        if (
          value === null ||
          value === undefined ||
          (typeof value === "string" && value === "")
        ) {
          delete obj[key];
        } else {
          obj[key] = removeEmptyStringsAndNulls(value);
        }
      }
    }
  }
  return obj;
}

export const categoryColorMap: Record<string, string> = {
  AI: "bg-orange-300/[.7]",
  SOCIAL: "bg-yellow-300/[.7]",
  TEXT: "bg-green-300/[.7]",
  SEARCH: "bg-blue-300/[.7]",