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

Code before:
    // 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 dark:bg-orange-700",
  SOCIAL: "bg-yellow-300 dark:bg-yellow-700",
  TEXT: "bg-green-300 dark:bg-green-700",
  SEARCH: "bg-blue-300 dark:bg-blue-700",
  BASIC: "bg-purple-300 dark:bg-purple-700",
  INPUT: "bg-cyan-300 dark:bg-cyan-700",
  OUTPUT: "bg-red-300 dark:bg-red-700",
  LOGIC: "bg-teal-300 dark:bg-teal-700",
  DEVELOPER_TOOLS: "bg-fuchsia-300 dark:bg-fuchsia-700",
  AGENT: "bg-lime-300 dark:bg-lime-700",
};

export function getPrimaryCategoryColor(categories: Category[]): string {
  if (categories.length === 0) {
    return "bg-gray-300 dark:bg-slate-700";
  }
  return (
    categoryColorMap[categories[0].category] || "bg-gray-300 dark:bg-slate-700"
  );
}

export enum BehaveAs {
  CLOUD = "CLOUD",
  LOCAL = "LOCAL",

Review comment (suggestion):
note to reviewers: `typeof value === "object"` includes arrays in JS

Code after:

export function pruneEmptyValues(
  obj: any,
  removeEmptyStrings: boolean = true,
): 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
        ? ""
        : pruneEmptyValues(item, removeEmptyStrings),
    );
  } 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)) continue;

      const value = obj[key];
      if (
        value === null ||
        value === undefined ||
        (typeof value === "string" && value === "" && removeEmptyStrings)
      ) {
        delete obj[key];
      } else if (typeof value === "object") {
        obj[key] = pruneEmptyValues(value, removeEmptyStrings);
      }
    }
  }
  return obj;
}

export function fillObjectDefaultsFromSchema(
  obj: Record<any, any>,
  schema: BlockIORootSchema | BlockIOObjectSubSchema,
) {
  for (const key in schema.properties) {
    if (!schema.properties.hasOwnProperty(key)) continue;

    const propertySchema = schema.properties[key];

    if ("default" in propertySchema && propertySchema.default !== undefined) {
      // Apply simple default values
      obj[key] ??= propertySchema.default;
    } else if (
      propertySchema.type === "object" &&
      "properties" in propertySchema
    ) {
      // Recursively fill defaults for nested objects
      obj[key] = fillObjectDefaultsFromSchema(obj[key] ?? {}, propertySchema);