Purpose
Demonstrate how to call an API with HTTP Header options and display the retrieved data in a structured table format.
Solution
The solution involves creating a table variable that will store the retrieved API data. We use CopyText with HTTP Header options to fetch data from a server.

Example: Fetch the 100 most recent commits from a Git server repository. The request URL format is:
http://[Authorization:token <api_access_token>]<server_ip/url>:<port>/api/v1/repos/<repository_creator>/<repository_name>/commits?sha=main&limit=100&page=1
GuiXT
// Clear the screen before execution
del (0,0) (20,200)

// Check if the commit table has already been created
if not V[commit_table.rowcount]
  // Create "commit_table" variable with columns
  CreateTable V[commit_table] commit_author_name commit_message sha
    
  Set V[api_token] "<api_access_token>"
  Set V[server_ip] "<server_ip/url>"
  Set V[server_port] "<port>"
  Set V[repository_creator] "<repository_creator>"
  Set V[repository_name] "<repository_name>"
  
  Set V[api_url] "http://[Authorization:token  &V[api_token]]" 
  Set V[api_url] "&V[api_url]&V[server_ip]:&V[server_port]"
  Set V[api_url] "&V[api_url]/api/v1/repos/&V[repository_creator]"
  Set V[api_url]  "&V[api_url]/&V[repository_name]"
  Set V[api_url] "&V[api_url]/commits?sha=main&limit=100&page=1"

  // Fetch commits from the Git server using API
  // with HTTP Header authorization
  CopyText _
    fromFile="&V[api_url]" _
    toText="commits" _
    -noCache

  // Filter JSON response to extract relevant fields
  CallJS commit_table = JSONUtils.filterJson "commits" _
  "commit_author_name,commit_message,sha"
endif

// Display the retrieved commits in a table
Table (1,22) (21,135) title="Commits" name="commit_table"
Column "Author Name" size=16 name="commit_author_name" -readOnly
Column "sha" size=16 name="sha" -readOnly
Column "Message" size=80 name="commit_message" -readOnly
JavaScript
// ------------------------------------------------------------
// Function: filterJson
// Purpose: Extract only the fields we want
// from a JSON array retrieved from an API
// Parameters:
//    jsonvar: name of the variable containing
//             JSON data (as a string)
//    fieldnames: comma-separated string of
//                field names to keep
// Returns:
//    Stringified JSON array containing only
//    the requested fields
// ------------------------------------------------------------
function filterJson(jsonvar, fieldnames) {

    // Step 1: Access GuiXT host environment
    let guixt = window.guixthost;

    // Step 2: Get text content of JSON variable
    let jsonString = guixt.gettext(jsonvar);

    // Step 3: Convert JSON string into JS object
    let data = JSON.parse(jsonString);

    // Step 4: Split fieldnames string into array
    const fields = fieldnames.split(",");

    // Step 5: Flatten nested objects for easier access
    const flattenedArray = data.map(item => 
        flattenObject(item)
    );

    // Step 6: Filter objects to keep only requested fields
    const filteredArray = flattenedArray.map(item => 
        filterObjectByKeys(item, fields)
    );

    // Step 7: Convert filtered array to readable JSON string
    const stringifiedJson = JSON.stringify(filteredArray, null, 2);

    // Step 8: Return final JSON string to GuiXT variable
    return stringifiedJson;
}

// ------------------------------------------------------------
// Function: flattenObject
// Purpose: Flatten nested JS object to a single-level
// Example: {commit:{author:{name:"Alice"}}}
//          -> {commit_author_name:"Alice"}
// ------------------------------------------------------------
function flattenObject(obj, parentKey = '', result = {}) {

    for (let key in obj) {
        if (!obj.hasOwnProperty(key)) continue;

        const newKey = parentKey ? `${parentKey}_${key}` : key;

        if (typeof obj[key] === 'object' && obj[key] !== null &&
            !Array.isArray(obj[key])) 
        {
            flattenObject(obj[key], newKey, result);
        } else {
            result[newKey] = obj[key];
        }
    }

    return result;
}

// ------------------------------------------------------------
// Function: filterObjectByKeys
// Purpose: Keep only keys listed in allowedKeys
// Example: obj={a:1,b:2,c:3}, allowedKeys=["a","c"]
//          -> {a:1,c:3}
// ------------------------------------------------------------
function filterObjectByKeys(obj, allowedKeys) {
    const result = {};

    for (const key of allowedKeys) {
        if (obj.hasOwnProperty(key)) {
            result[key] = obj[key];
        }
    }

    return result;
}

Components
InputAssistant + Controls