function processPayloadSchema()

in scripts/inference-providers/scripts/generate.ts [243:376]


function processPayloadSchema(schema: any): JsonObject[] {
  let rows: JsonObject[] = [];

  // Helper function to resolve schema references
  function resolveRef(ref: string) {
    const refPath = ref.split("#/")[1].split("/");
    let refSchema = ref.includes("common-definitions.json")
      ? COMMON_DEFINITIONS
      : schema;
    for (const part of refPath) {
      refSchema = refSchema[part];
    }
    return refSchema;
  }

  // Helper function to process a schema node
  function processSchemaNode(
    key: string,
    value: any,
    required: boolean,
    parentPrefix: string,
  ): void {
    const isRequired = required;
    let type = value.type || "unknown";
    let description = value.description || "";

    if (value.$ref) {
      // Resolve the reference
      value = resolveRef(value.$ref);
      type = value.type || "unknown";
      description = value.description || "";
    }

    if (value.enum) {
      type = "enum";
      description = `Possible values: ${value.enum.join(", ")}.`;
    }

    const isObject = type === "object" && value.properties;
    const isArray = type === "array" && value.items;
    const isCombinator = value.oneOf || value.allOf || value.anyOf;
    const addRow =
      !(isCombinator && isCombinator.length === 1) &&
      !description.includes("UNUSED") &&
      !key.includes("SKIP") &&
      key.length > 0;

    if (isCombinator && isCombinator.length > 1) {
      description = "One of the following:";
    }

    if (isArray) {
      if (value.items.$ref) {
        type = "object[]";
      } else if (value.items.type) {
        type = `${value.items.type}[]`;
      }
    }

    if (addRow) {
      // Add the row to the table except if combination with only one option
      if (key.includes("(#")) {
        // If it's a combination, no need to re-specify the type except if it's to
        // specify a constant value.
        type = value.const ? `'${value.const}'` : type;
      }
      const row = {
        name: `${parentPrefix}${key}`,
        type: type,
        description: description.replace(/\n/g, " "),
        required: isRequired,
      };
      rows.push(row);
    }

    if (isObject) {
      // Recursively process nested objects
      Object.entries(value.properties || {}).forEach(
        ([nestedKey, nestedValue]) => {
          const nestedRequired = value.required?.includes(nestedKey);
          processSchemaNode(
            nestedKey,
            nestedValue,
            nestedRequired,
            parentPrefix + TABLE_INDENT,
          );
        },
      );
    } else if (isArray) {
      // Process array items
      processSchemaNode("SKIP", value.items, false, parentPrefix);
    } else if (isCombinator) {
      // Process combinators like oneOf, allOf, anyOf
      const combinators = value.oneOf || value.allOf || value.anyOf;
      if (combinators.length === 1) {
        // If there is only one option, process it directly
        processSchemaNode(key, combinators[0], isRequired, parentPrefix);
      } else {
        // If there are multiple options, process each one as options
        combinators.forEach((subSchema: any, index: number) => {
          processSchemaNode(
            `${NBSP}(#${index + 1})`,
            subSchema,
            false,
            parentPrefix + TABLE_INDENT,
          );
        });
      }
    }
  }

  // Start processing based on the root type of the schema
  if (schema.type === "array") {
    // If the root schema is an array, process its items
    const row = {
      name: "(array)",
      type: `${schema.items.type}[]`,
      description:
        schema.items.description ||
        `Output is an array of ${schema.items.type}s.`,
      required: true,
    };
    rows.push(row);
    processSchemaNode("", schema.items, false, "");
  } else {
    // Otherwise, start with the root object
    Object.entries(schema.properties || {}).forEach(([key, value]) => {
      const required = schema.required?.includes(key);
      processSchemaNode(key, value, required, "");
    });
  }

  return rows;
}