Extract CodeEngine Functions

Python
DomoCodeEngine
Author

Jae Wilson

Published

April 4, 2024

import datetime as dt
import os
import re

from enum import Enum
from functools import partial

import domolibrary.client.DomoAuth as dmda
import domolibrary.classes.DomoDatacenter as dmdc
token_auth = dmda.DomoTokenAuth(
    domo_instance=os.environ['DOMO_INSTANCE'],
    domo_access_token=os.environ["DOMO_ACCESS_TOKEN"],
)
domo_versions = await dmdc.DomoDatacenter.search_codeengine(auth=token_auth)

# remove codeengine packages that don't parse
domo_versions = [
    domo_version for domo_version in domo_versions if domo_version.functions
]
domo_versions[0:5]
'NoneType' object has no attribute 'group'
expected string or bytes-like object, got 'NoneType'
'NoneType' object has no attribute 'group'
'NoneType' object has no attribute 'group'
expected string or bytes-like object, got 'NoneType'
expected string or bytes-like object, got 'NoneType'
expected string or bytes-like object, got 'NoneType'
'NoneType' object has no attribute 'group'
[DomoCodeEngine_PackageVersion(package_id='aaee1eca-aea9-4d8a-b402-c1855f8f86a2', version='1.0.1', language='JAVASCRIPT', description=None, createdby_id='1893952720', released_dt=None, configuration={'accountsMapping': [{'accountId': '124', 'alias': 'account'}], 'mlModel': [], 'externalPackageMapping': {}}, createdby=None, accounts_mapping=[{'accountId': '124', 'alias': 'account'}], ml_model=[], functions=[DomoCodeEngine_Function(name='generateAuthHeader', displayName='Generate Auth Header', description='', language='JAVASCRIPT', code='async function generateAuthHeader(\n  accountName,\n  headers = {},\n  isAbstract = false\n) {\n  const creds = await retrieveAccountCreds(accountName, isAbstract);\n\n  return { ...headers, "x-domo-developer-token": creds.domoAccessToken };\n}\n\nasync function getData(\n  method,\n  url,\n  accountName,\n  headers = {},\n  params = {},\n  bodyJson = null, // codeengine inputs must be typed\n  bodyStr = null, // codeengine inputs must be typed\n  debugApi = false,\n  debugPrn = false\n) {\n  if (debugApi) {\n    console.log({\n      url,\n      method,\n      body: bodyStr || bodyJson,\n    });\n  }\n\n  let res, data;\n  if (!accountName || accountName === null) {\n    if (debugPrn) {\n      console.log("🌵 - using user_auth");\n    }\n    url = url.split(".domo.com/")[1];\n    res = await codeEngine.sendRequest(method, url, bodyJson || bodyStr);\n\n    return { status: 200, response: res, isSuccess: true };\n  } else {\n    if (debugPrn) {\n      console.log("🌵 - using SUDO_auth");\n    }\n\n    headers = await generateAuthHeader(accountName, headers, false);\n\n    res = await codeEngine.axios(url, {\n      method,\n      headers,\n      params,\n      data: bodyJson || bodyStr,\n    });\n    data = await res.data;\n  }\n\n  if (res.status >= 400) {\n    throw new Error(`HTTP error! status: ${res.status}`);\n  }\n\n  return {\n    status: res.status,\n    response: data,\n    isSuccess: res.status < 400,\n  };\n}\n\nasync function sharePage(\n  page_id,\n  group_id,\n  accountName,\n  domoInstance,\n  debugApi = true,\n  debugPrn = false\n) {\n  const body = {\n    resources: [{ type: "page", id: page_id }],\n    recipients: [{ type: "group", id: group_id }],\n    message: "I thought you might find this page interesting.",\n  };\n\n  return await getData(\n    "POST",\n    `https://${domoInstance}.domo.com/api/content/v1/share`,\n    accountName,\n    null,\n    null,\n    body,\n    null,\n    debugApi,\n    debugPrn\n  );\n}\n\nasync function getPages(\n  accountName,\n  domoInstance,\n  debugApi = true,\n  debugPrn = false\n) {\n  const body = {\n    includeVirtual: false,\n    includePageTitleClause: true,\n    orderBy: "parentPageTitlePageTitle",\n    pageTitleSearchText: "",\n    includeDataAppViews: true,\n  };\n\n  const res = await getData(\n    "POST",\n    `https://${domoInstance}.domo.com/api/content/v1/pages/adminsummary`,\n    accountName,\n    null,\n    null,\n    body,\n    null,\n    debugApi,\n    debugPrn\n  );\n\n  res.response = res.response.pageAdminSummaries;\n\n  return res;\n}\n', code_prefix=None), DomoCodeEngine_Function(name='getData', displayName='Get Data', description='', language='JAVASCRIPT', code='async function getData(\n  method,\n  url,\n  accountName,\n  headers = {},\n  params = {},\n  bodyJson = null, // codeengine inputs must be typed\n  bodyStr = null, // codeengine inputs must be typed\n  debugApi = false,\n  debugPrn = false\n) {\n  if (debugApi) {\n    console.log({\n      url,\n      method,\n      body: bodyStr || bodyJson,\n    });\n  }\n\n  let res, data;\n  if (!accountName || accountName === null) {\n    if (debugPrn) {\n      console.log("🌵 - using user_auth");\n    }\n    url = url.split(".domo.com/")[1];\n    res = await codeEngine.sendRequest(method, url, bodyJson || bodyStr);\n\n    return { status: 200, response: res, isSuccess: true };\n  } else {\n    if (debugPrn) {\n      console.log("🌵 - using SUDO_auth");\n    }\n\n    headers = await generateAuthHeader(accountName, headers, false);\n\n    res = await codeEngine.axios(url, {\n      method,\n      headers,\n      params,\n      data: bodyJson || bodyStr,\n    });\n    data = await res.data;\n  }\n\n  if (res.status >= 400) {\n    throw new Error(`HTTP error! status: ${res.status}`);\n  }\n\n  return {\n    status: res.status,\n    response: data,\n    isSuccess: res.status < 400,\n  };\n}\n\nasync function sharePage(\n  page_id,\n  group_id,\n  accountName,\n  domoInstance,\n  debugApi = true,\n  debugPrn = false\n) {\n  const body = {\n    resources: [{ type: "page", id: page_id }],\n    recipients: [{ type: "group", id: group_id }],\n    message: "I thought you might find this page interesting.",\n  };\n\n  return await getData(\n    "POST",\n    `https://${domoInstance}.domo.com/api/content/v1/share`,\n    accountName,\n    null,\n    null,\n    body,\n    null,\n    debugApi,\n    debugPrn\n  );\n}\n\nasync function getPages(\n  accountName,\n  domoInstance,\n  debugApi = true,\n  debugPrn = false\n) {\n  const body = {\n    includeVirtual: false,\n    includePageTitleClause: true,\n    orderBy: "parentPageTitlePageTitle",\n    pageTitleSearchText: "",\n    includeDataAppViews: true,\n  };\n\n  const res = await getData(\n    "POST",\n    `https://${domoInstance}.domo.com/api/content/v1/pages/adminsummary`,\n    accountName,\n    null,\n    null,\n    body,\n    null,\n    debugApi,\n    debugPrn\n  );\n\n  res.response = res.response.pageAdminSummaries;\n\n  return res;\n}\n', code_prefix=None), DomoCodeEngine_Function(name='getPages', displayName='Get Pages', description='', language='JAVASCRIPT', code='async function getPages(\n  accountName,\n  domoInstance,\n  debugApi = true,\n  debugPrn = false\n) {\n  const body = {\n    includeVirtual: false,\n    includePageTitleClause: true,\n    orderBy: "parentPageTitlePageTitle",\n    pageTitleSearchText: "",\n    includeDataAppViews: true,\n  };\n\n  const res = await getData(\n    "POST",\n    `https://${domoInstance}.domo.com/api/content/v1/pages/adminsummary`,\n    accountName,\n    null,\n    null,\n    body,\n    null,\n    debugApi,\n    debugPrn\n  );\n\n  res.response = res.response.pageAdminSummaries;\n\n  return res;\n}\n', code_prefix=None), DomoCodeEngine_Function(name='retrieveAccountCreds', displayName='Retrieve Account Creds', description='', language='JAVASCRIPT', code='async function retrieveAccountCreds(accountName, isAbstract = false) {\n  const creds = await codeEngine.getAccount(accountName);\n  const properties = creds.properties;\n\n  return !isAbstract ? properties : properties.credentials;\n}\n\nasync function generateAuthHeader(\n  accountName,\n  headers = {},\n  isAbstract = false\n) {\n  const creds = await retrieveAccountCreds(accountName, isAbstract);\n\n  return { ...headers, "x-domo-developer-token": creds.domoAccessToken };\n}\n\nasync function getData(\n  method,\n  url,\n  accountName,\n  headers = {},\n  params = {},\n  bodyJson = null, // codeengine inputs must be typed\n  bodyStr = null, // codeengine inputs must be typed\n  debugApi = false,\n  debugPrn = false\n) {\n  if (debugApi) {\n    console.log({\n      url,\n      method,\n      body: bodyStr || bodyJson,\n    });\n  }\n\n  let res, data;\n  if (!accountName || accountName === null) {\n    if (debugPrn) {\n      console.log("🌵 - using user_auth");\n    }\n    url = url.split(".domo.com/")[1];\n    res = await codeEngine.sendRequest(method, url, bodyJson || bodyStr);\n\n    return { status: 200, response: res, isSuccess: true };\n  } else {\n    if (debugPrn) {\n      console.log("🌵 - using SUDO_auth");\n    }\n\n    headers = await generateAuthHeader(accountName, headers, false);\n\n    res = await codeEngine.axios(url, {\n      method,\n      headers,\n      params,\n      data: bodyJson || bodyStr,\n    });\n    data = await res.data;\n  }\n\n  if (res.status >= 400) {\n    throw new Error(`HTTP error! status: ${res.status}`);\n  }\n\n  return {\n    status: res.status,\n    response: data,\n    isSuccess: res.status < 400,\n  };\n}\n\nasync function sharePage(\n  page_id,\n  group_id,\n  accountName,\n  domoInstance,\n  debugApi = true,\n  debugPrn = false\n) {\n  const body = {\n    resources: [{ type: "page", id: page_id }],\n    recipients: [{ type: "group", id: group_id }],\n    message: "I thought you might find this page interesting.",\n  };\n\n  return await getData(\n    "POST",\n    `https://${domoInstance}.domo.com/api/content/v1/share`,\n    accountName,\n    null,\n    null,\n    body,\n    null,\n    debugApi,\n    debugPrn\n  );\n}\n\nasync function getPages(\n  accountName,\n  domoInstance,\n  debugApi = true,\n  debugPrn = false\n) {\n  const body = {\n    includeVirtual: false,\n    includePageTitleClause: true,\n    orderBy: "parentPageTitlePageTitle",\n    pageTitleSearchText: "",\n    includeDataAppViews: true,\n  };\n\n  const res = await getData(\n    "POST",\n    `https://${domoInstance}.domo.com/api/content/v1/pages/adminsummary`,\n    accountName,\n    null,\n    null,\n    body,\n    null,\n    debugApi,\n    debugPrn\n  );\n\n  res.response = res.response.pageAdminSummaries;\n\n  return res;\n}\n', code_prefix=None), DomoCodeEngine_Function(name='sharePage', displayName='Share Page', description='', language='JAVASCRIPT', code='async function sharePage(\n  page_id,\n  group_id,\n  accountName,\n  domoInstance,\n  debugApi = true,\n  debugPrn = false\n) {\n  const body = {\n    resources: [{ type: "page", id: page_id }],\n    recipients: [{ type: "group", id: group_id }],\n    message: "I thought you might find this page interesting.",\n  };\n\n  return await getData(\n    "POST",\n    `https://${domoInstance}.domo.com/api/content/v1/share`,\n    accountName,\n    null,\n    null,\n    body,\n    null,\n    debugApi,\n    debugPrn\n  );\n}\n\nasync function getPages(\n  accountName,\n  domoInstance,\n  debugApi = true,\n  debugPrn = false\n) {\n  const body = {\n    includeVirtual: false,\n    includePageTitleClause: true,\n    orderBy: "parentPageTitlePageTitle",\n    pageTitleSearchText: "",\n    includeDataAppViews: true,\n  };\n\n  const res = await getData(\n    "POST",\n    `https://${domoInstance}.domo.com/api/content/v1/pages/adminsummary`,\n    accountName,\n    null,\n    null,\n    body,\n    null,\n    debugApi,\n    debugPrn\n  );\n\n  res.response = res.response.pageAdminSummaries;\n\n  return res;\n}\n', code_prefix=None)]),
 DomoCodeEngine_PackageVersion(package_id='b1c21da8-2c37-491f-8067-7ad75346c6fc', version='1.0.0', language='JAVASCRIPT', description=None, createdby_id='1893952720', released_dt=None, configuration={'accountsMapping': [], 'mlModel': [], 'externalPackageMapping': {}}, createdby=None, accounts_mapping=[], ml_model=[], functions=[DomoCodeEngine_Function(name='setMyLandingPage', displayName='Set My Landing Page', description='update the users landing page', language='JAVASCRIPT', code='async function setMyLandingPage(objectId, objectType ) {\n    if (!([\'CARD\', \'PAGE\'].includes(objectType))) {\n      throw new Error("🤯 invalid inputs:  `objectType` must be \'PAGE\' or \'CARD\'");\n    }\n    \n    const url = `/api/content/v1/landings/target/DESKTOP/entity/${objectType}/id/${String(objectId)}/me`\n    \n    try{\n      let r = await codeengine.sendRequest(\'put\', url, {})\n      return true\n        \n     } catch(err) {\n        throw new Error(`🤯 API Error: ${err.status} - ${err.statusReason} -- check valid \\`objectId\\` (is it shared with you?)`);\n    }\n} \n\n\n', code_prefix=None)]),
 DomoCodeEngine_PackageVersion(package_id='fc484f87-4e05-45a5-8e1b-8f6fac8cac5b', version='1.0.0', language='PYTHON', description=None, createdby_id='1893952720', released_dt=None, configuration={'accountsMapping': [], 'mlModel': [], 'externalPackageMapping': {}}, createdby=None, accounts_mapping=[], ml_model=[], functions=[DomoCodeEngine_Function(name='greeting', displayName='Greeting', description='', language='PYTHON', code='def greeting(name): \n  print("Hello " + name)\n  return "Hello " + name', code_prefix=None)]),
 DomoCodeEngine_PackageVersion(package_id='615380ce-bede-4720-88e6-7c5b7a57f4a4', version='1.0.0', language='JAVASCRIPT', description=None, createdby_id='1950208331', released_dt=datetime.datetime(2024, 7, 26, 16, 3, 26, 793000, tzinfo=tzlocal()), configuration={'accountsMapping': [], 'mlModel': [], 'externalPackageMapping': {}}, createdby=None, accounts_mapping=[], ml_model=[], functions=[DomoCodeEngine_Function(name='cloneUserAttributes', displayName='Clone User Attributes', description='', language='JAVASCRIPT', code="async function cloneUserAttributes(primaryUserId, secondaryUserId) {\n  try {\n    // Fetch primary user details to get role ID\n    const primaryUserDetails = await Helpers.handleRequest('get', `/api/content/v3/users/${primaryUserId}?includeDetails=true`);\n    const primaryUserRoleId = primaryUserDetails.roleId;\n    console.log('Primary User Role ID:', primaryUserRoleId);\n\n    // Fetch groups of the primary user\n    const primaryUserGroupsResponse = await Helpers.handleRequest('get', `/api/content/v2/groups/grouplist?ascending=true&includeDeleted=false&includeSupport=false&limit=100&members=${primaryUserId}&offset=0&sort=name`);\n    console.log('Primary User Groups Response:', primaryUserGroupsResponse);\n\n    // Extract groups from the response\n    const primaryUserGroups = primaryUserGroupsResponse || [];\n    console.log('Extracted Primary User Groups:', primaryUserGroups);\n\n    // Update secondary user's role to match primary user's role\n    await Helpers.handleRequest('put', `/api/authorization/v1/roles/${primaryUserRoleId}/users`, [secondaryUserId]);\n    console.log(`Role cloned from user ${primaryUserId} to user ${secondaryUserId}`);\n\n    // Add secondary user to the same groups as primary user\n    for (const group of primaryUserGroups) {\n      console.log(`Adding user ${secondaryUserId} to group ${group.groupId}`);\n      await codeengine.sendRequest('put', `/api/content/v2/groups/${group.groupId}/user`, [secondaryUserId]);\n    }\n\n    console.log(`Successfully cloned role and groups from user ${primaryUserId} to user ${secondaryUserId}`);\n  } catch (error) {\n    console.error('Error cloning user attributes:', error);\n    throw error;\n  }\n}\n", code_prefix=None), DomoCodeEngine_Function(name='copyPDPPolicies', displayName='Copy P D P Policies', description='', language='JAVASCRIPT', code="async function copyPDPPolicies(dataset1Id, dataset2Id) {\n  const fetchPoliciesUrl = `/api/query/v1/data-control/${dataset1Id}/filter-groups?options=load_associations,include_open_policy,load_filters,sort`;\n  const applyPoliciesUrl = `/api/query/v1/data-control/${dataset2Id}/filter-groups?options=load_associations,include_open_policy,load_filters,sort`;\n\n  try {\n    // Fetch PDP policies from dataset1\n    const policiesResponse = await codeengine.sendRequest('GET', fetchPoliciesUrl);\n    if (!policiesResponse || policiesResponse.length === 0) {\n      throw new Error('No PDP policies found in dataset1');\n    }\n\n    const policies = policiesResponse.map(policy => ({\n      ...policy,\n      datasetId: dataset2Id // Change dataset ID to dataset2Id\n    }));\n\n    // Apply PDP policies to dataset2\n    for (const policy of policies) {\n      await codeengine.sendRequest('POST', applyPoliciesUrl, policy);\n    }\n\n    console.log('PDP policies copied successfully from dataset1 to dataset2');\n  } catch (error) {\n    console.error('Error copying PDP policies:', error);\n    throw error;\n  }\n}\n\n\n", code_prefix=None), DomoCodeEngine_Function(name='deletePage', displayName='Delete Page', description='', language='JAVASCRIPT', code="async function deletePage(pageId) {\n  try {\n    await codeengine.sendRequest('DELETE', `/api/content/v1/pages/${pageId}`);\n    return true;\n  } catch (error) {\n    console.error(`Error deleting page with ID ${pageId}:`, error);\n    throw new Error(`Unable to delete page with ID ${pageId}.`);\n  }\n}\n\n\n", code_prefix=None), DomoCodeEngine_Function(name='mergeAndSharePages', displayName='Merge And Share Pages', description='', language='JAVASCRIPT', code="async function mergeAndSharePages(pageid1, pageid2) {\n\n  async function sharePageWithRecipients(recipients, pageId, recipientType) {\n    const body = {\n      resources: [\n        {\n          type: 'page',\n          id: pageId,\n        },\n      ],\n      recipients: recipients.map(recipient => ({\n        type: recipientType,\n        id: recipient.id,\n      })),\n      message: `I thought you might find this page interesting.`,\n    };\n\n    try {\n      await codeEngine.sendRequest('POST', '/api/content/v1/share', body);\n    } catch (err) {\n      throw new Error(`Failed to share page with ${recipientType}s: ${err.message}`);\n    }\n  }\n\n  try {\n    const fetchAccessUrl1 = `/api/content/v1/share/accesslist/page/${pageid1}?expandUsers=false`;\n    const fetchAccessUrl2 = `/api/content/v1/share/accesslist/page/${pageid2}?expandUsers=false`;\n\n    // Fetch the shared access lists for both pages\n    const [accessPage1, accessPage2] = await Promise.all([\n      codeEngine.sendRequest('GET', fetchAccessUrl1),\n      codeEngine.sendRequest('GET', fetchAccessUrl2)\n    ]);\n\n    console.log('Access Page 1:', accessPage1);\n    console.log('Access Page 2:', accessPage2);\n\n    // Extract users and groups from the access lists, handling cases where they might not exist\n    const usersPage1 = accessPage1.users || [];\n    const usersPage2 = accessPage2.users || [];\n    const groupsPage1 = accessPage1.groups || [];\n    const groupsPage2 = accessPage2.groups || [];\n\n    // Combine users and groups ensuring no duplicates\n    const combinedUsers = [...new Map(usersPage1.concat(usersPage2).map(user => [user.id, user])).values()];\n    const combinedGroups = [...new Map(groupsPage1.concat(groupsPage2).map(group => [group.id, group])).values()];\n\n    // Share pageid2 with combined users\n    if (combinedUsers.length > 0) {\n      await sharePageWithRecipients(combinedUsers, pageid2, 'user');\n    }\n\n    // Share pageid2 with combined groups\n    if (combinedGroups.length > 0) {\n      await sharePageWithRecipients(combinedGroups, pageid2, 'group');\n    }\n\n    console.log(`Page ${pageid2} successfully shared with combined users and groups from pages ${pageid1} and ${pageid2}`);\n  } catch (error) {\n    console.error('Error merging and sharing pages:', error);\n    throw error;\n  }\n}\n\n\n", code_prefix=None), DomoCodeEngine_Function(name='removeAllUsersExceptOwners', displayName='Remove All Users Except Owners', description='', language='JAVASCRIPT', code="async function removeAllUsersExceptOwners(pageId) {\n  async function getPageUsers(pageId) {\n    const url = `/api/content/v1/share/accesslist/page/${pageId}?expandUsers=false`;\n    return await codeengine.sendRequest('GET', url);\n  }\n\n  async function getPageOwners(pageId) {\n    const url = `/api/content/v1/pages/${pageId}?parts=owners`;\n    const page = await codeengine.sendRequest('GET', url);\n    return page.owners.map(owner => owner.id);\n  }\n\n  async function revokeUserAccess(pageId, userId) {\n    const url = `/api/content/v1/share/page/${pageId}/user/${userId}`;\n    await codeengine.sendRequest('DELETE', url);\n  }\n\n  try {\n    const { users } = await getPageUsers(pageId);\n    const ownerIds = await getPageOwners(pageId);\n\n    for (let user of users) {\n      if (!ownerIds.includes(user.id)) {\n        await revokeUserAccess(pageId, user.id);\n        console.log(`Revoked access for user ${user.id}`);\n      }\n    }\n    console.log('Successfully removed non-owners from the page.');\n  } catch (error) {\n    console.error('Error removing non-owners:', error);\n  }\n}\n\n\n", code_prefix=None), DomoCodeEngine_Function(name='updateAllCardTitles', displayName='Update All Card Titles', description='', language='JAVASCRIPT', code='async function updateAllCardTitles(pageId) {\n  const fetchPageUrl = `api/content/v1/pages/${pageId}/cards`; // Endpoint to fetch all cards on a page\n\n  try {\n    // Fetch all card IDs from the page\n    const pageResponse = await codeengine.sendRequest(\'GET\', fetchPageUrl);\n    if (!pageResponse || pageResponse.length === 0) {\n      throw new Error(\'No cards found on the page\');\n    }\n\n    const cardIds = pageResponse.map(card => card.id);\n\n    for (const cardId of cardIds) {\n      const fetchUrl = `api/content/v1/cards?urns=${cardId}&parts=metadata,metadataOverrides,problems,properties,certification,datasources,dateInfo,domoapp,drillPath,drillPathURNs,library,masonData,owner,owners,problems,properties,slicers&includeFiltered=true`; // Endpoint to fetch card details\n      const updateUrl = `/api/content/v1/cards/${cardId}/title`; // Endpoint to update card title\n\n      try {\n        // Fetch the current card details\n        const response = await codeengine.sendRequest(\'GET\', fetchUrl);\n        if (!response || response.length === 0) {\n          throw new Error(`No card data found for card ID: ${cardId}`);\n        }\n\n        const currentTitle = response[0].title;\n        if (!currentTitle) {\n          throw new Error(`Title not found in card data for card ID: ${cardId}`);\n        }\n\n        // Remove "Duplicate of " from the title\n        const newTitle = currentTitle.replace(/^Duplicate of /, \'\');\n\n        // Update the card with the new title\n        const payload = { title: newTitle };\n        await codeengine.sendRequest(\'PUT\', updateUrl, payload);\n\n      } catch (error) {\n        console.error(`Error updating card title for card ID: ${cardId}`, error); // Log the error for debugging\n      }\n    }\n\n    return true;\n  } catch (error) {\n    console.error(\'Error updating card titles:\', error); // Log the error for debugging\n    throw error;\n  }\n}\n\n\n', code_prefix=None), DomoCodeEngine_Function(name='updateAllCardTitlesAndDatasources', displayName='Update All Card Titles And Datasources', description='', language='JAVASCRIPT', code='async function updateAllCardTitlesAndDatasources(pageId, newDatasourceId) {\n  const fetchPageUrl = `api/content/v1/pages/${pageId}/cards`; // Endpoint to fetch all cards on a page\n\n  try {\n    // Fetch all card IDs from the page\n    const pageResponse = await codeengine.sendRequest(\'GET\', fetchPageUrl);\n    if (!pageResponse || pageResponse.length === 0) {\n      throw new Error(\'No cards found on the page\');\n    }\n\n    const cardIds = pageResponse.map(card => card.id);\n\n    const fetchUrl = cardId => `api/content/v1/cards?urns=${cardId}&parts=metadata,metadataOverrides,problems,properties,certification,datasources,dateInfo,domoapp,drillPath,drillPathURNs,library,masonData,owner,owners,slicers&includeFiltered=true`; // Endpoint to fetch card details\n    const updateTitleUrl = cardId => `/api/content/v1/cards/${cardId}/title`; // Endpoint to update card title\n    const updateDatasourceUrl = cardId => `/api/content/v1/cards/${cardId}/datasource/${newDatasourceId}`; // Endpoint to update card datasource\n\n    // Fetch all card details concurrently\n    const cardDetailsPromises = cardIds.map(cardId => codeengine.sendRequest(\'GET\', fetchUrl(cardId)).then(response => ({ cardId, response })).catch(error => ({ cardId, error })));\n    const cardDetailsResults = await Promise.all(cardDetailsPromises);\n\n    for (const { cardId, response, error } of cardDetailsResults) {\n      if (error) {\n        console.error(`Error fetching card details for card ID: ${cardId}`, error);\n        continue;\n      }\n\n      if (!response || response.length === 0) {\n        console.error(`No card data found for card ID: ${cardId}`);\n        continue;\n      }\n\n      const { title: currentTitle } = response[0];\n      if (!currentTitle) {\n        console.error(`Title not found in card data for card ID: ${cardId}`);\n        continue;\n      }\n\n      // Remove "Duplicate of " from the title\n      const newTitle = currentTitle.replace(/^Duplicate of /, \'\');\n\n      // Update the card title\n      try {\n        const titlePayload = { title: newTitle };\n        await codeengine.sendRequest(\'PUT\', updateTitleUrl(cardId), titlePayload);\n      } catch (updateTitleError) {\n        console.error(`Error updating card title for card ID: ${cardId}`, updateTitleError);\n      }\n\n      // Update the card datasource\n      try {\n        const datasourcePayload = { datasourceId: newDatasourceId }; // Assuming this is the correct payload structure\n        await codeengine.sendRequest(\'PUT\', updateDatasourceUrl(cardId), datasourcePayload);\n      } catch (updateDatasourceError) {\n        console.error(`Error updating datasource for card ID: ${cardId}`, updateDatasourceError);\n      }\n    }\n\n    return true;\n  } catch (error) {\n    console.error(\'Error updating card titles and datasources:\', error); // Log the error for debugging\n    throw error;\n  }\n}\n\n\n', code_prefix=None)]),
 DomoCodeEngine_PackageVersion(package_id='02b77ae9-fc21-40c7-8a62-d9d735e2db9c', version='3.1.0', language='JAVASCRIPT', description='', createdby_id='1658438246', released_dt=datetime.datetime(2024, 8, 30, 16, 48, 3, 288000, tzinfo=tzlocal()), configuration={'accountsMapping': [], 'mlModel': [], 'externalPackageMapping': {}}, createdby=None, accounts_mapping=[], ml_model=[], functions=[DomoCodeEngine_Function(name='addOwnerToDataset', displayName='Add Owner To DataSet', description='Define the user as an owner of the specified DataSet', language='JAVASCRIPT', code='async function addOwnerToDataset(dataset, owner) {\n  try {\n    await addOwnersToDataset(dataset, [owner]);\n    return true;\n  } catch (error) {\n    throw new Error(error);\n  }\n}\n\n\n', code_prefix=None), DomoCodeEngine_Function(name='addOwnersToDataset', displayName='Add Owners To DataSet', description='Define all specified users as owners of the given DataSet', language='JAVASCRIPT', code="async function addOwnersToDataset(dataset, owners) {\n  const api = `/api/data/v3/datasources/${dataset}/share`;\n  const permissions = (owners || []).map(\n    DatasetPermissionInitiator.createDatasetOwnerPermission,\n  );\n  const body = {\n    permissions,\n    sendEmail: true,\n  };\n\n  try {\n    await codeengine.sendRequest('post', api, body);\n    return true;\n  } catch (error) {\n    throw new Error(error);\n  }\n}\n\n\n", code_prefix=None), DomoCodeEngine_Function(name='appendToDataset', displayName='Append To DataSet', description='Append a list of text to a DataSet', language='JAVASCRIPT', code="async function appendToDataset(dataset, values, delimiter) {\n  const uploadsUrl = UPLOADS_URL.replace(':id', dataset);\n  const uploadsBody = {\n    action: 'APPEND',\n    message: 'Uploading',\n    appendId: 'latest',\n  };\n\n  try {\n    const uploadsResponse = await codeengine.sendRequest(\n      'post',\n      uploadsUrl,\n      uploadsBody,\n    );\n    const partsUrl = UPLOADS_PARTS_URL.replace(':id', dataset).replace(\n      ':uploadId',\n      uploadsResponse.uploadId,\n    );\n\n    const splitValue = values.split(delimiter || ',');\n\n    const csvValue = listToCSV(splitValue);\n\n    await codeengine.sendRequest('put', partsUrl, csvValue, null, 'text/csv');\n\n    const commitUrl = UPLOADS_COMMIT_URL.replace(':id', dataset).replace(\n      ':uploadId',\n      uploadsResponse.uploadId,\n    );\n    const commitBody = {\n      index: true,\n      appendId: 'latest',\n      message: 'it worked',\n    };\n\n    return await codeengine.sendRequest(\n      'put',\n      commitUrl,\n      commitBody,\n      null,\n      'application/json',\n    );\n  } catch (error) {\n    console.error(error);\n  }\n}\n\n\n", code_prefix=None), DomoCodeEngine_Function(name='createDatasetTag', displayName='Create DataSet Tag', description='Create and assign a DataSet tag for the specified DataSet', language='JAVASCRIPT', code="async function createDatasetTag(dataset, tag) {\n  const url = `/api/data/ui/v3/datasources/${dataset}/tags`;\n\n  try {\n    await codeengine.sendRequest('POST', url, [tag]);\n\n    return true;\n  } catch (e) {\n    throw e;\n  }\n}\n\nclass DatasetPermissionInitiator {\n  static createDatasetOwnerPermission(ownerId) {\n    return {\n      id: ownerId,\n      type: 'USER',\n      accessLevel: 'CO_OWNER',\n    };\n  }\n}\n\n\n", code_prefix=None), DomoCodeEngine_Function(name='getDatasetOwner', displayName='Get DataSet Owner', description='Get the DataSet owner', language='JAVASCRIPT', code='async function getDatasetOwner(dataset) {\n  try {\n    const datasetResult = await getMetadata(dataset);\n    return datasetResult.owner.id;\n  } catch (error) {\n    throw error;\n  }\n}\n\n\n', code_prefix=None), DomoCodeEngine_Function(name='getFirstMatch', displayName='Get First Match', description='This function gets the first match based on the provided SQL query', language='JAVASCRIPT', code="async function getFirstMatch(dataset, sql) {\n  const limitToOne = sql => {\n    if (/LIMIT \\d+/i.test(sql)) return sql.replace(/LIMIT \\d+/i, 'LIMIT 1');\n\n    return `${sql} LIMIT 1`;\n  };\n\n  try {\n    const response = await queryWithSql(dataset, limitToOne(sql));\n\n    if (Array.isArray(response)) return response[0];\n    return response;\n  } catch (e) {\n    console.error(e);\n    throw new Error('Failed to execute SQL query', e);\n  }\n}\n\n\n", code_prefix=None), DomoCodeEngine_Function(name='getMetadata', displayName='Get Metadata', description='Get the metadata for the specified DataSet', language='JAVASCRIPT', code="async function getMetadata(dataset, requestedParts) {\n  const parts = requestedParts?.trim() ?? DATASET_PARTS.join(',');\n  const url = `${DATASET_URL.replace(':id', dataset)}?part=${parts}`;\n\n  try {\n    return await codeengine.sendRequest('get', url);\n  } catch (error) {\n    console.error(error);\n  }\n}\n\n\n", code_prefix=None), DomoCodeEngine_Function(name='getNumberOfCardsPoweredByDataset', displayName='Get Number Of Cards Powered By DataSet', description='Get the number of cards powered by the specified DataSet', language='JAVASCRIPT', code='async function getNumberOfCardsPoweredByDataset(dataset) {\n  try {\n    const datasetResult = await getMetadata(dataset);\n    return datasetResult.cardCount;\n  } catch (error) {\n    throw error;\n  }\n}\n\n\n', code_prefix=None), DomoCodeEngine_Function(name='getNumberOfDataflowsPoweredByDataset', displayName='Get Number Of Dataflows Powered By DataSet', description='Get the number of DataFlows that are powered by the provided DataSet', language='JAVASCRIPT', code="async function getNumberOfDataflowsPoweredByDataset(dataset) {\n  const url = `${DATASET_URL.replace(':id', dataset)}?includeAllDetails=true`;\n\n  try {\n    const datasetResult = await codeengine.sendRequest('get', url);\n    return datasetResult.dataFlowCount;\n  } catch (error) {\n    throw error;\n  }\n}\n\n\n", code_prefix=None), DomoCodeEngine_Function(name='getValueFor', displayName='Get Value For', description='Get a value based on a specific condition', language='JAVASCRIPT', code='async function getValueFor(dataset, field, where, value) {\n  try {\n    const query = `SELECT * FROM table WHERE ${where} = \'${value}\' LIMIT 1`;\n    const response = await getFirstMatch(dataset, query);\n\n    if (!response) return \'\';\n    if (!response.hasOwnProperty(field))\n      throw new Error(\n        "The requested field doesn\'t exist on the returned object",\n        response,\n      );\n\n    return response[field] ? `${response[field]}` : \'\';\n  } catch (e) {\n    console.log(e);\n    throw new Error(\'The query failed to execute\', e);\n  }\n}\n\n\n', code_prefix=None), DomoCodeEngine_Function(name='listToCSV', displayName='List To C S V', description='', language='JAVASCRIPT', code='function listToCSV(values) {\n  return values\n    .map(value => {\n      if (\n        typeof value === \'string\' &&\n        (value.includes(\',\') || value.includes(\'"\') || value.includes(\'\\n\'))\n      ) {\n        return `"${value.replace(/"/g, \'""\')}"`;\n      }\n      return value;\n    })\n    .join(\',\');\n}\n\n\n', code_prefix=None), DomoCodeEngine_Function(name='queryWithSql', displayName='Query With SQL', description='Query for data matching the provided SQL statement', language='JAVASCRIPT', code="async function queryWithSql(dataset, sql) {\n  const convertResponseToList = ({rows, columns}) => {\n    return rows.map(row => {\n      return row.reduce((acc, curr, index) => {\n        acc[columns[index]] = curr;\n        return acc;\n      }, {});\n    });\n  };\n\n  try {\n    const url = QUERY_URL.replace(':id', dataset);\n    const body = {sql};\n    const response = await codeengine.sendRequest('post', url, body);\n    return convertResponseToList(response);\n  } catch (error) {\n    console.error(error);\n  }\n}\n\n\n", code_prefix=None), DomoCodeEngine_Function(name='removePeopleFromDataset', displayName='Remove People From DataSet', description="Remove people from a DataSet's permissions", language='JAVASCRIPT', code='async function removePeopleFromDataset(dataset, people) {\n  try {\n    await Promise.all(\n      (people || []).map(person => removePersonFromDataset(dataset, person)),\n    );\n    return true;\n  } catch (error) {\n    throw new Error(error);\n  }\n}\n\n\n', code_prefix=None), DomoCodeEngine_Function(name='removePersonFromDataset', displayName='Remove Person From DataSet', description='Remove the specified person from the DataSet', language='JAVASCRIPT', code="async function removePersonFromDataset(dataset, person) {\n  const api = `/api/data/v3/datasources/${dataset}/USERS/${person}`;\n\n  try {\n    await codeengine.sendRequest('delete', api);\n    return true;\n  } catch (error) {\n    throw new Error(error);\n  }\n}\n\n\n", code_prefix=None), DomoCodeEngine_Function(name='revokeDatasetAccess', displayName='Revoke DataSet Access', description='Remove the specified users access to the provided DataSet', language='JAVASCRIPT', code="async function revokeDatasetAccess(dataset, person) {\n  try {\n    const url = `/api/data/v3/datasources/${dataset}/permissions/USER/${person}`;\n\n    await codeengine.sendRequest('DELETE', url);\n    return true;\n  } catch (e) {\n    throw new Error(e);\n  }\n}\n\n\n", code_prefix=None), DomoCodeEngine_Function(name='runDataset', displayName='Run DataSet', description='Instruct a DataSet to run', language='JAVASCRIPT', code="async function runDataset(dataset) {\n  const api = `/api/data/v3/datasources/${dataset}`;\n\n  try {\n    const response = await codeengine.sendRequest(\n      'get',\n      api,\n      null,\n      null,\n      'application/json',\n    );\n    const runApi = `/api/data/v1/streams/${response.streamId}/executions`;\n    return await codeengine.sendRequest('post', runApi, {runType: 'MANUAL'});\n  } catch (error) {\n    console.error(error);\n  }\n}\n\n\n", code_prefix=None), DomoCodeEngine_Function(name='secondsSinceUpdated', displayName='Seconds Since Updated', description='Queries for the last updated value and calculates the number of seconds since', language='JAVASCRIPT', code='async function secondsSinceUpdated(dataset) {\n  try {\n    const response = await getMetadata(dataset);\n    return response\n      ? (Date.now() - new Date(response.lastUpdated).getTime()) / 1000\n      : 0;\n  } catch (error) {\n    console.error(error);\n    return 0;\n  }\n}\n\n\n', code_prefix=None), DomoCodeEngine_Function(name='truncateDataset', displayName='Truncate DataSet', description='Truncate a DataSet', language='JAVASCRIPT', code='async function truncateDataset(dataset) {\n  try {\n    // Step 1: Start a new upload and get the data version\n    const apiNewUpload = `/api/data/v3/datasources/${dataset}/uploads`;\n    const dataVersion = await codeengine.sendRequest(\'POST\', apiNewUpload, {});\n\n    // Step 2: Upload data\n    const apiDataUpload = `/api/data/v3/datasources/${dataset}/uploads/${dataVersion.uploadId}/parts/1`;\n    await codeengine.sendRequest(\'PUT\', apiDataUpload, \'\', null, \'text/plain\');\n\n    // Step 3: Commit upload\n    const apiCommitUpload = `/api/data/v3/datasources/${dataset}/uploads/${dataVersion.uploadId}/commit`;\n    const bodyCommitUpload = {index: false, action: \'REPLACE\'};\n    await codeengine.sendRequest(\'PUT\', apiCommitUpload, bodyCommitUpload);\n\n    // Step 4: Index DataSet\n    const apiIndexDataset = `/api/data/v3/datasources/${dataset}/indexes`;\n    const bodyIndexDataset = {...bodyCommitUpload, index: true};\n    await codeengine.sendRequest(\'POST\', apiIndexDataset, bodyIndexDataset);\n\n    return true;\n  } catch (error) {\n    return false;\n  }\n}\n\nfunction listToCSV(values) {\n  return values\n    .map(value => {\n      if (\n        typeof value === \'string\' &&\n        (value.includes(\',\') || value.includes(\'"\') || value.includes(\'\\n\'))\n      ) {\n        return `"${value.replace(/"/g, \'""\')}"`;\n      }\n      return value;\n    })\n    .join(\',\');\n}\n\n\n', code_prefix=None)])]
domo_function = next(
    (
        domo_function
        for domo_version in domo_versions
        for domo_function in domo_version.functions
        if domo_function.language == "JAVASCRIPT" and "url" in domo_function.code
    )
)
domo_function.code
'async function generateAuthHeader(\n  accountName,\n  headers = {},\n  isAbstract = false\n) {\n  const creds = await retrieveAccountCreds(accountName, isAbstract);\n\n  return { ...headers, "x-domo-developer-token": creds.domoAccessToken };\n}\n\nasync function getData(\n  method,\n  url,\n  accountName,\n  headers = {},\n  params = {},\n  bodyJson = null, // codeengine inputs must be typed\n  bodyStr = null, // codeengine inputs must be typed\n  debugApi = false,\n  debugPrn = false\n) {\n  if (debugApi) {\n    console.log({\n      url,\n      method,\n      body: bodyStr || bodyJson,\n    });\n  }\n\n  let res, data;\n  if (!accountName || accountName === null) {\n    if (debugPrn) {\n      console.log("🌵 - using user_auth");\n    }\n    url = url.split(".domo.com/")[1];\n    res = await codeEngine.sendRequest(method, url, bodyJson || bodyStr);\n\n    return { status: 200, response: res, isSuccess: true };\n  } else {\n    if (debugPrn) {\n      console.log("🌵 - using SUDO_auth");\n    }\n\n    headers = await generateAuthHeader(accountName, headers, false);\n\n    res = await codeEngine.axios(url, {\n      method,\n      headers,\n      params,\n      data: bodyJson || bodyStr,\n    });\n    data = await res.data;\n  }\n\n  if (res.status >= 400) {\n    throw new Error(`HTTP error! status: ${res.status}`);\n  }\n\n  return {\n    status: res.status,\n    response: data,\n    isSuccess: res.status < 400,\n  };\n}\n\nasync function sharePage(\n  page_id,\n  group_id,\n  accountName,\n  domoInstance,\n  debugApi = true,\n  debugPrn = false\n) {\n  const body = {\n    resources: [{ type: "page", id: page_id }],\n    recipients: [{ type: "group", id: group_id }],\n    message: "I thought you might find this page interesting.",\n  };\n\n  return await getData(\n    "POST",\n    `https://${domoInstance}.domo.com/api/content/v1/share`,\n    accountName,\n    null,\n    null,\n    body,\n    null,\n    debugApi,\n    debugPrn\n  );\n}\n\nasync function getPages(\n  accountName,\n  domoInstance,\n  debugApi = true,\n  debugPrn = false\n) {\n  const body = {\n    includeVirtual: false,\n    includePageTitleClause: true,\n    orderBy: "parentPageTitlePageTitle",\n    pageTitleSearchText: "",\n    includeDataAppViews: true,\n  };\n\n  const res = await getData(\n    "POST",\n    `https://${domoInstance}.domo.com/api/content/v1/pages/adminsummary`,\n    accountName,\n    null,\n    null,\n    body,\n    null,\n    debugApi,\n    debugPrn\n  );\n\n  res.response = res.response.pageAdminSummaries;\n\n  return res;\n}\n'
def extract_is_url(code):
    if not "url" in code:
        return False

    return True


extract_is_url(domo_function.code)
True
def extract_url(code):
    pattern_ls = [r"const url = `(.*?)`;", r"const url = (.*?);\n"]

    for pattern in pattern_ls:
        match = re.search(pattern, code)

        if match:
            return match.group(1)


extract_url(domo_function.code)
def extract_method(code):
    pattern = r'\.sendRequest\(\s*["\'](.*?)["\']\s*,'

    match = re.search(pattern, code, re.DOTALL)

    if match:
        return match.group(1).upper()

    else:
        return None


extract_method(domo_function.code)
def extract_body(code):

    # pattern = r'\.sendRequest\("[^"\*",\s*[^,]*,\s*([^)]*)\)'
    # pattern = r'\.sendRequest\("[^"]*",\s*[^,]*,\s*([^)]*)\)'
    pattern = r"codeengine\.sendRequest\([^,]*,\s*[^,]*,\s*([^)]*)\)"

    match = re.search(pattern, code, re.DOTALL)

    if match:
        return match.group(1)

    else:
        return None


extract_body(domo_function.code)
def extract_api_call_params(code):
    return {
        "is_url": extract_is_url(code),
        "method": extract_method(code),
        "url": extract_url(code),
        "body": extract_body(code),
    }


# print(domo_function)
domo_function.code
# extract_api_call_params(domo_function.code)
'async function generateAuthHeader(\n  accountName,\n  headers = {},\n  isAbstract = false\n) {\n  const creds = await retrieveAccountCreds(accountName, isAbstract);\n\n  return { ...headers, "x-domo-developer-token": creds.domoAccessToken };\n}\n\nasync function getData(\n  method,\n  url,\n  accountName,\n  headers = {},\n  params = {},\n  bodyJson = null, // codeengine inputs must be typed\n  bodyStr = null, // codeengine inputs must be typed\n  debugApi = false,\n  debugPrn = false\n) {\n  if (debugApi) {\n    console.log({\n      url,\n      method,\n      body: bodyStr || bodyJson,\n    });\n  }\n\n  let res, data;\n  if (!accountName || accountName === null) {\n    if (debugPrn) {\n      console.log("🌵 - using user_auth");\n    }\n    url = url.split(".domo.com/")[1];\n    res = await codeEngine.sendRequest(method, url, bodyJson || bodyStr);\n\n    return { status: 200, response: res, isSuccess: true };\n  } else {\n    if (debugPrn) {\n      console.log("🌵 - using SUDO_auth");\n    }\n\n    headers = await generateAuthHeader(accountName, headers, false);\n\n    res = await codeEngine.axios(url, {\n      method,\n      headers,\n      params,\n      data: bodyJson || bodyStr,\n    });\n    data = await res.data;\n  }\n\n  if (res.status >= 400) {\n    throw new Error(`HTTP error! status: ${res.status}`);\n  }\n\n  return {\n    status: res.status,\n    response: data,\n    isSuccess: res.status < 400,\n  };\n}\n\nasync function sharePage(\n  page_id,\n  group_id,\n  accountName,\n  domoInstance,\n  debugApi = true,\n  debugPrn = false\n) {\n  const body = {\n    resources: [{ type: "page", id: page_id }],\n    recipients: [{ type: "group", id: group_id }],\n    message: "I thought you might find this page interesting.",\n  };\n\n  return await getData(\n    "POST",\n    `https://${domoInstance}.domo.com/api/content/v1/share`,\n    accountName,\n    null,\n    null,\n    body,\n    null,\n    debugApi,\n    debugPrn\n  );\n}\n\nasync function getPages(\n  accountName,\n  domoInstance,\n  debugApi = true,\n  debugPrn = false\n) {\n  const body = {\n    includeVirtual: false,\n    includePageTitleClause: true,\n    orderBy: "parentPageTitlePageTitle",\n    pageTitleSearchText: "",\n    includeDataAppViews: true,\n  };\n\n  const res = await getData(\n    "POST",\n    `https://${domoInstance}.domo.com/api/content/v1/pages/adminsummary`,\n    accountName,\n    null,\n    null,\n    body,\n    null,\n    debugApi,\n    debugPrn\n  );\n\n  res.response = res.response.pageAdminSummaries;\n\n  return res;\n}\n'
def javascript_multiline():
    return "/*\n", "*/\n\n"


def python_multiline():
    return '"""\n', '"""\n\n'


class multiline_factory(Enum):
    PYTHON = partial(python_multiline)
    JAVASCRIPT = partial(javascript_multiline)

EXPORT FUNCTIONS

import domolibrary.classes.DomoCodeEngine as dmce
import domolibrary.utils.chunk_execution as ce


async def handle_export_function(domo_version, domo_function):

    domo_package = await dmce.DomoCodeEngine_Package.get_by_id(
        auth=domo_version.auth, package_id=domo_version.package_id
    )
    domo_version.name = domo_package.name

    output_folder = f"EXPORT/_code_engine/{domo_version.name}/{domo_function.version}/"

    file_name = domo_function.export(
        output_folder=output_folder, file_name=domo_function.name, debug_prn=False
    )

    params = extract_api_call_params(domo_function.code)

    if not params:
        return

    multiline_fn = multiline_factory[domo_function.language].value
    start, end = multiline_fn()

    with open(file_name, "r+") as f:
        content = f.read()
        f.seek(0, 0)

        f.write(start)
        f.writelines([f"{key} - {value}\n" for key, value in params.items() if value])
        f.write(end)

        f.write(content)

    return file_name


await ce.gather_with_concurrency(
    *[
        handle_export_function(domo_version=domo_version, domo_function=domo_function)
        for domo_version in domo_versions
        for domo_function in domo_version.functions
    ],
    n=10,
)
['EXPORT/_code_engine/javascript/1.0.1/generateAuthHeader.js',
 'EXPORT/_code_engine/javascript/1.0.1/getData.js',
 'EXPORT/_code_engine/javascript/1.0.1/getPages.js',
 'EXPORT/_code_engine/javascript/1.0.1/retrieveAccountCreds.js',
 'EXPORT/_code_engine/javascript/1.0.1/sharePage.js',
 'EXPORT/_code_engine/domoContent/1.0.0/setMyLandingPage.js',
 'EXPORT/_code_engine/python/1.0.0/greeting.py',
 'EXPORT/_code_engine/Domo Admin Operations Functions Sample/1.0.0/cloneUserAttributes.js',
 'EXPORT/_code_engine/Domo Admin Operations Functions Sample/1.0.0/copyPDPPolicies.js',
 'EXPORT/_code_engine/Domo Admin Operations Functions Sample/1.0.0/deletePage.js',
 'EXPORT/_code_engine/Domo Admin Operations Functions Sample/1.0.0/mergeAndSharePages.js',
 'EXPORT/_code_engine/Domo Admin Operations Functions Sample/1.0.0/removeAllUsersExceptOwners.js',
 'EXPORT/_code_engine/Domo Admin Operations Functions Sample/1.0.0/updateAllCardTitles.js',
 'EXPORT/_code_engine/Domo Admin Operations Functions Sample/1.0.0/updateAllCardTitlesAndDatasources.js',
 'EXPORT/_code_engine/DOMO DataSets/3.1.0/addOwnerToDataset.js',
 'EXPORT/_code_engine/DOMO DataSets/3.1.0/addOwnersToDataset.js',
 'EXPORT/_code_engine/DOMO DataSets/3.1.0/appendToDataset.js',
 'EXPORT/_code_engine/DOMO DataSets/3.1.0/createDatasetTag.js',
 'EXPORT/_code_engine/DOMO DataSets/3.1.0/getDatasetOwner.js',
 'EXPORT/_code_engine/DOMO DataSets/3.1.0/getFirstMatch.js',
 'EXPORT/_code_engine/DOMO DataSets/3.1.0/getMetadata.js',
 'EXPORT/_code_engine/DOMO DataSets/3.1.0/getNumberOfCardsPoweredByDataset.js',
 'EXPORT/_code_engine/DOMO DataSets/3.1.0/getNumberOfDataflowsPoweredByDataset.js',
 'EXPORT/_code_engine/DOMO DataSets/3.1.0/getValueFor.js',
 'EXPORT/_code_engine/DOMO DataSets/3.1.0/listToCSV.js',
 'EXPORT/_code_engine/DOMO DataSets/3.1.0/queryWithSql.js',
 'EXPORT/_code_engine/DOMO DataSets/3.1.0/removePeopleFromDataset.js',
 'EXPORT/_code_engine/DOMO DataSets/3.1.0/removePersonFromDataset.js',
 'EXPORT/_code_engine/DOMO DataSets/3.1.0/revokeDatasetAccess.js',
 'EXPORT/_code_engine/DOMO DataSets/3.1.0/runDataset.js',
 'EXPORT/_code_engine/DOMO DataSets/3.1.0/secondsSinceUpdated.js',
 'EXPORT/_code_engine/DOMO DataSets/3.1.0/truncateDataset.js',
 'EXPORT/_code_engine/DOMO Scheduled Reports/2.0.6/sendCardReportToGroups.js',
 'EXPORT/_code_engine/DOMO Scheduled Reports/2.0.6/sendCardReportToPeople.js',
 'EXPORT/_code_engine/DOMO Scheduled Reports/2.0.6/sendPageReportToGroups.js',
 'EXPORT/_code_engine/DOMO Scheduled Reports/2.0.6/sendPageReportToPeople.js',
 'EXPORT/_code_engine/DOMO Text Utilities/2.0.4/booleanToText.js',
 'EXPORT/_code_engine/DOMO Text Utilities/2.0.4/combineText.js',
 'EXPORT/_code_engine/DOMO Text Utilities/2.0.4/convertTextToBoolean.js',
 'EXPORT/_code_engine/DOMO Text Utilities/2.0.4/convertTextToDecimal.js',
 'EXPORT/_code_engine/DOMO Text Utilities/2.0.4/convertTextToNumber.js',
 'EXPORT/_code_engine/DOMO Text Utilities/2.0.4/convertTextToObject.js',
 'EXPORT/_code_engine/DOMO Text Utilities/2.0.4/dateTimeToText.js',
 'EXPORT/_code_engine/DOMO Text Utilities/2.0.4/dateToText.js',
 'EXPORT/_code_engine/DOMO Text Utilities/2.0.4/decimalToText.js',
 'EXPORT/_code_engine/DOMO Text Utilities/2.0.4/isValidEmail.js',
 'EXPORT/_code_engine/DOMO Text Utilities/2.0.4/numberToText.js',
 'EXPORT/_code_engine/DOMO Text Utilities/2.0.4/objectToText.js',
 'EXPORT/_code_engine/DOMO Text Utilities/2.0.4/textSubstitution.js',
 'EXPORT/_code_engine/DOMO Text Utilities/2.0.4/timeToText.js',
 'EXPORT/_code_engine/Google Sheets/3.0.0/getSheet.js',
 'EXPORT/_code_engine/DOMO Notifications/2.1.6/buildTable.js',
 'EXPORT/_code_engine/DOMO Notifications/2.1.6/sendBuzzRequest.js',
 'EXPORT/_code_engine/DOMO Notifications/2.1.6/sendBuzzRequestByChannelName.js',
 'EXPORT/_code_engine/DOMO Notifications/2.1.6/sendEmail.js',
 'EXPORT/_code_engine/DOMO Notifications/2.1.6/sendEmailToGroup.js',
 'EXPORT/_code_engine/DOMO Notifications/2.1.6/sendEmailToGroups.js',
 'EXPORT/_code_engine/DOMO Notifications/2.1.6/sendEmailToListOfEmails.js',
 'EXPORT/_code_engine/DOMO Notifications/2.1.6/sendEmailToPeople.js',
 'EXPORT/_code_engine/DOMO Notifications/2.1.6/sendEmailToPerson.js',
 'EXPORT/_code_engine/DOMO Notifications/2.1.6/sendExternalEmail.js',
 'EXPORT/_code_engine/DOMO Sandbox/2.0.0/assignOwner.js',
 'EXPORT/_code_engine/DOMO Sandbox/2.0.0/commitRepository.js',
 'EXPORT/_code_engine/DOMO Sandbox/2.0.0/createAppRepository.js',
 'EXPORT/_code_engine/DOMO Sandbox/2.0.0/createCardRepository.js',
 'EXPORT/_code_engine/DOMO Sandbox/2.0.0/createConnectorRepository.js',
 'EXPORT/_code_engine/DOMO Sandbox/2.0.0/createDataflowRepository.js',
 'EXPORT/_code_engine/DOMO Sandbox/2.0.0/createPageRepository.js',
 'EXPORT/_code_engine/DOMO Sandbox/2.0.0/createViewRepository.js',
 'EXPORT/_code_engine/DOMO Sandbox/2.0.0/fetchRepositoryById.js',
 'EXPORT/_code_engine/DOMO Sandbox/2.0.0/listRepositories.js',
 'EXPORT/_code_engine/DOMO Sandbox/2.0.0/promoteRepository.js',
 'EXPORT/_code_engine/DOMO Sandbox/2.0.0/shareRepository.js',
 'EXPORT/_code_engine/DOMO AppDB Collections/2.0.9/createAppDBDocument.js',
 'EXPORT/_code_engine/DOMO AppDB Collections/2.0.9/createAppDBDocuments.js',
 'EXPORT/_code_engine/DOMO AppDB Collections/2.0.9/getAppDBDocument.js',
 'EXPORT/_code_engine/DOMO AppDB Collections/2.0.9/getMaxValue.js',
 'EXPORT/_code_engine/DOMO AppDB Collections/2.0.9/getMaxValues.js',
 'EXPORT/_code_engine/DOMO AppDB Collections/2.0.9/partialUpdate.js',
 'EXPORT/_code_engine/DOMO AppDB Collections/2.0.9/searchAppDBDocuments.js',
 'EXPORT/_code_engine/DOMO AppDB Collections/2.0.9/syncCollection.js',
 'EXPORT/_code_engine/DOMO AppDB Collections/2.0.9/updateField.js',
 'EXPORT/_code_engine/DOMO Observability Metrics/1.0.1/cloneJob.js',
 'EXPORT/_code_engine/DOMO Observability Metrics/1.0.1/copySettings.js',
 'EXPORT/_code_engine/DOMO Observability Metrics/1.0.1/createDomoAccessTokenAccount.js',
 'EXPORT/_code_engine/DOMO Observability Metrics/1.0.1/createOrEditJob.js',
 'EXPORT/_code_engine/DOMO Observability Metrics/1.0.1/deleteJob.js',
 'EXPORT/_code_engine/DOMO Observability Metrics/1.0.1/getAccountIdByName.js',
 'EXPORT/_code_engine/DOMO Observability Metrics/1.0.1/getJobIdByJobName.js',
 'EXPORT/_code_engine/DOMO Observability Metrics/1.0.1/listJobs.js',
 'EXPORT/_code_engine/DOMO Observability Metrics/1.0.1/runJob.js',
 'EXPORT/_code_engine/DOMO Observability Metrics/1.0.1/setSchedule.js',
 'EXPORT/_code_engine/Asana/1.0.0/getProjectInfo.js',
 'EXPORT/_code_engine/Asana/1.0.0/getProjectTasks.js',
 'EXPORT/_code_engine/Asana/1.0.0/getTaskComments.js',
 'EXPORT/_code_engine/Asana/1.0.0/getTaskInfo.js',
 'EXPORT/_code_engine/Asana/1.0.0/getTaskSubtasks.js',
 'EXPORT/_code_engine/Asana/1.0.0/makeApiRequest.js',
 'EXPORT/_code_engine/Asana/1.0.0/updateTask.js',
 'EXPORT/_code_engine/DOMO Alerts/2.0.0/addSubscriptionToPerson.js',
 'EXPORT/_code_engine/DOMO Alerts/2.0.0/deleteAlert.js',
 'EXPORT/_code_engine/DOMO Alerts/2.0.0/removeSubscriptionFromPerson.js',
 'EXPORT/_code_engine/DOMO Alerts/2.0.0/shareAlertToPerson.js',
 'EXPORT/_code_engine/DOMO Connector/2.0.4/createMysqlConnector.js',
 'EXPORT/_code_engine/DOMO Connector/2.0.4/isMysqlConfigValid.js',
 'EXPORT/_code_engine/DOMO Connector/2.0.4/runConnector.js',
 'EXPORT/_code_engine/BigQuery/1.0.1/cancelJob.js',
 'EXPORT/_code_engine/BigQuery/1.0.1/createTable.js',
 'EXPORT/_code_engine/BigQuery/1.0.1/getDataset.js',
 'EXPORT/_code_engine/BigQuery/1.0.1/getJob.js',
 'EXPORT/_code_engine/BigQuery/1.0.1/getTable.js',
 'EXPORT/_code_engine/BigQuery/1.0.1/getTableSchema.js',
 'EXPORT/_code_engine/BigQuery/1.0.1/insertRows.js',
 'EXPORT/_code_engine/BigQuery/1.0.1/listDatasets.js',
 'EXPORT/_code_engine/BigQuery/1.0.1/listJobs.js',
 'EXPORT/_code_engine/BigQuery/1.0.1/listProjects.js',
 'EXPORT/_code_engine/BigQuery/1.0.1/listTables.js',
 'EXPORT/_code_engine/BigQuery/1.0.1/queryData.js',
 'EXPORT/_code_engine/BigQuery/1.0.1/request.js',
 'EXPORT/_code_engine/BigQuery/1.0.1/startJob.js',
 'EXPORT/_code_engine/DOMO Cards/1.0.5/addCardToPage.js',
 'EXPORT/_code_engine/DOMO Cards/1.0.5/addCardToPages.js',
 'EXPORT/_code_engine/DOMO Cards/1.0.5/addOwnerToCard.js',
 'EXPORT/_code_engine/DOMO Cards/1.0.5/allowTableDrill.js',
 'EXPORT/_code_engine/DOMO Cards/1.0.5/changeCardDescription.js',
 'EXPORT/_code_engine/DOMO Cards/1.0.5/changeCardTitle.js',
 'EXPORT/_code_engine/DOMO Cards/1.0.5/disableCardInsights.js',
 'EXPORT/_code_engine/DOMO Cards/1.0.5/disallowTableDrill.js',
 'EXPORT/_code_engine/DOMO Cards/1.0.5/enableCardInsights.js',
 'EXPORT/_code_engine/DOMO Cards/1.0.5/lockCard.js',
 'EXPORT/_code_engine/DOMO Cards/1.0.5/removeOwnerFromCard.js',
 'EXPORT/_code_engine/DOMO Cards/1.0.5/revokeCardAccess.js',
 'EXPORT/_code_engine/DOMO Cards/1.0.5/unlockCard.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/absoluteValue.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/addDecimalAndNumber.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/addDecimals.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/addNumbers.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/arccosine.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/arcsine.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/arctangent.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/cosine.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/cubeRoot.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/decimalToNumber.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/degreesToRadians.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/divideDecimalByNumber.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/divideDecimals.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/divideNumberByDecimal.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/divideNumbers.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/eulerConstant.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/exponent.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/findBiggestNumber.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/findSmallestNumber.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/floor.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/log.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/multiplyDecimalByNumber.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/multiplyDecimals.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/multiplyNumbers.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/numberToDecimal.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/radiansToDegrees.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/randomNumber.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/rateOfIncrease.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/round.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/signOfANumber.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/sine.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/squareRoot.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/subtractDecimalByNumber.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/subtractDecimals.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/subtractNumbers.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/subtractNumbersByDecimal.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/tangent.js',
 'EXPORT/_code_engine/DOMO Math/2.0.5/valueOfPi.js',
 'EXPORT/_code_engine/DOMO Pages/1.0.3/createSubPage.js',
 'EXPORT/_code_engine/DOMO Pages/1.0.3/makePageTopLevel.js',
 'EXPORT/_code_engine/DOMO Pages/1.0.3/revokePageAccess.js',
 'EXPORT/_code_engine/DOMO Workflow Executions/1.0.0/getExecutionCustomer.js',
 'EXPORT/_code_engine/DOMO Workflow Executions/1.0.0/getExecutionDetails.js',
 'EXPORT/_code_engine/DOMO Workflow Executions/1.0.0/getExecutionEntityDetails.js',
 'EXPORT/_code_engine/DOMO Workflow Executions/1.0.0/getExecutionEntityType.js',
 'EXPORT/_code_engine/DOMO Workflow Executions/1.0.0/getExecutionHostName.js',
 'EXPORT/_code_engine/DOMO Workflow Executions/1.0.0/getExecutionInstanceId.js',
 'EXPORT/_code_engine/DOMO Workflow Executions/1.0.0/getExecutionModelId.js',
 'EXPORT/_code_engine/DOMO Workflow Executions/1.0.0/getExecutionVersion.js',
 'EXPORT/_code_engine/DOMO Workflow Executions/1.0.0/getExecutor.js',
 'EXPORT/_code_engine/DOMO Users/3.0.3/bulkUpdateUserRoles.js',
 'EXPORT/_code_engine/DOMO Users/3.0.3/createUser.js',
 'EXPORT/_code_engine/DOMO Users/3.0.3/deleteUser.js',
 'EXPORT/_code_engine/DOMO Users/3.0.3/displayName.js',
 'EXPORT/_code_engine/DOMO Users/3.0.3/emailAddress.js',
 'EXPORT/_code_engine/DOMO Users/3.0.3/fetchPerson.js',
 'EXPORT/_code_engine/DOMO Users/3.0.3/fetchUser.js',
 'EXPORT/_code_engine/DOMO Users/3.0.3/getPersonFromList.js',
 'EXPORT/_code_engine/DOMO Users/3.0.3/getRoleIdByName.js',
 'EXPORT/_code_engine/DOMO Users/3.0.3/getRoleNames.js',
 'EXPORT/_code_engine/DOMO Users/3.0.3/getRoles.js',
 'EXPORT/_code_engine/DOMO Users/3.0.3/inviteUser.js',
 'EXPORT/_code_engine/DOMO Users/3.0.3/updateUserRole.js',
 'EXPORT/_code_engine/DOMO Beastmode/1.0.3/getBeastmode.js',
 'EXPORT/_code_engine/DOMO Beastmode/1.0.3/updateBeastmode.js',
 'EXPORT/_code_engine/DOMO Content Sharing/3.0.1/lockPage.js',
 'EXPORT/_code_engine/DOMO Content Sharing/3.0.1/shareApp.js',
 'EXPORT/_code_engine/DOMO Content Sharing/3.0.1/shareAppWithGroup.js',
 'EXPORT/_code_engine/DOMO Content Sharing/3.0.1/shareAppWithGroups.js',
 'EXPORT/_code_engine/DOMO Content Sharing/3.0.1/shareAppWithPeople.js',
 'EXPORT/_code_engine/DOMO Content Sharing/3.0.1/shareAppWithPerson.js',
 'EXPORT/_code_engine/DOMO Content Sharing/3.0.1/shareCardWithGroup.js',
 'EXPORT/_code_engine/DOMO Content Sharing/3.0.1/shareCardWithGroups.js',
 'EXPORT/_code_engine/DOMO Content Sharing/3.0.1/shareCardWithPeople.js',
 'EXPORT/_code_engine/DOMO Content Sharing/3.0.1/shareCardWithPerson.js',
 'EXPORT/_code_engine/DOMO Content Sharing/3.0.1/shareDataSet.js',
 'EXPORT/_code_engine/DOMO Content Sharing/3.0.1/sharePageWithGroup.js',
 'EXPORT/_code_engine/DOMO Content Sharing/3.0.1/sharePageWithGroups.js',
 'EXPORT/_code_engine/DOMO Content Sharing/3.0.1/sharePageWithPeople.js',
 'EXPORT/_code_engine/DOMO Content Sharing/3.0.1/sharePageWithPerson.js',
 'EXPORT/_code_engine/DOMO Content Sharing/3.0.1/shareResource.js',
 'EXPORT/_code_engine/DOMO Groups/3.0.1/addPeopleToGroup.js',
 'EXPORT/_code_engine/DOMO Groups/3.0.1/createGroup.js',
 'EXPORT/_code_engine/DOMO Groups/3.0.1/displayName.js',
 'EXPORT/_code_engine/DOMO Groups/3.0.1/fetchGroup.js',
 'EXPORT/_code_engine/DOMO Groups/3.0.1/fetchMembers.js',
 'EXPORT/_code_engine/DOMO Groups/3.0.1/removePeopleFromGroup.js',
 'EXPORT/_code_engine/DOMO Groups/3.0.1/removePersonFromGroup.js',
 'EXPORT/_code_engine/Microsoft Teams/1.0.1/buildMentionObject.js',
 'EXPORT/_code_engine/Microsoft Teams/1.0.1/getChannels.js',
 'EXPORT/_code_engine/Microsoft Teams/1.0.1/getChatDetails.js',
 'EXPORT/_code_engine/Microsoft Teams/1.0.1/getChats.js',
 'EXPORT/_code_engine/Microsoft Teams/1.0.1/getTeams.js',
 'EXPORT/_code_engine/Microsoft Teams/1.0.1/getUsers.js',
 'EXPORT/_code_engine/Microsoft Teams/1.0.1/makeApiRequest.js',
 'EXPORT/_code_engine/Microsoft Teams/1.0.1/postMessageToChannel.js',
 'EXPORT/_code_engine/Microsoft Teams/1.0.1/postMessageToChat.js',
 'EXPORT/_code_engine/DOMO PDP Management/1.0.0/createPolicy.js',
 'EXPORT/_code_engine/DOMO PDP Management/1.0.0/deletePolicy.js',
 'EXPORT/_code_engine/DOMO PDP Management/1.0.0/enablePDP.js',
 'EXPORT/_code_engine/DOMO PDP Management/1.0.0/getPDPPolicies.js',
 'EXPORT/_code_engine/DOMO PDP Management/1.0.0/updatePolicy.js',
 'EXPORT/_code_engine/DOMO Certified Content/1.0.0/certifyCard.js',
 'EXPORT/_code_engine/DOMO Certified Content/1.0.0/certifyDataset.js',
 'EXPORT/_code_engine/DOMO Certified Content/1.0.0/deleteCardCertification.js',
 'EXPORT/_code_engine/DOMO Certified Content/1.0.0/deleteDatasetCertification.js',
 'EXPORT/_code_engine/DOMO Certified Content/1.0.0/getCertificationStatus.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/addSubscribersToPublication.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/addUsersToPolicy.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/createDynamicPolicy.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/createInstance.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/createPublication.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/createSubscriber.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/enableDatasetPdp.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/findTargetPolicy.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/getAllRowsPolicy.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/getAppDatasets.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/getCardEmbedId.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/getDashboardEmbedId.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/getEmbedPublicLinkValue.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/getInstances.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/getNamedPolicy.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/getPageDatasets.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/getPolicy.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/getPublication.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/getPublicationCount.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/getPublications.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/getSubscriberDomains.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/getSubscriberVirtualUserIds.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/getSubscribers.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/getUsedPolicies.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/processNewSubscriberPermissions.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/processPermissions.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/refreshPublication.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/removeUsersFromPolicy.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/updateAppPublication.js',
 'EXPORT/_code_engine/DOMO Everywhere/3.0.0/updatePagePublication.js',
 'EXPORT/_code_engine/Domo User Governance/2.0.1/bulkUpdateUserRoles.js',
 'EXPORT/_code_engine/Domo User Governance/2.0.1/deleteUser.js',
 'EXPORT/_code_engine/Domo User Governance/2.0.1/getRoleIdByName.js',
 'EXPORT/_code_engine/Domo User Governance/2.0.1/getRoleNames.js',
 'EXPORT/_code_engine/Domo User Governance/2.0.1/getRoles.js',
 'EXPORT/_code_engine/Domo User Governance/2.0.1/handleRequest.js',
 'EXPORT/_code_engine/Domo User Governance/2.0.1/inviteUser.js',
 'EXPORT/_code_engine/Domo User Governance/2.0.1/updateUserRole.js',
 'EXPORT/_code_engine/DOMO OpenAI/1.0.0/askForBeastmode.js',
 'EXPORT/_code_engine/DOMO OpenAI/1.0.0/askForSQL.js',
 'EXPORT/_code_engine/DOMO OpenAI/1.0.0/askForText.js',
 'EXPORT/_code_engine/DOMO OpenAI/1.0.0/fetchCollectionSchema.js',
 'EXPORT/_code_engine/AirTable/1.0.0/batchCreateRecords.js',
 'EXPORT/_code_engine/AirTable/1.0.0/batchUpdateRecords.js',
 'EXPORT/_code_engine/AirTable/1.0.0/createRecord.js',
 'EXPORT/_code_engine/AirTable/1.0.0/deleteRecord.js',
 'EXPORT/_code_engine/AirTable/1.0.0/getBaseTables.js',
 'EXPORT/_code_engine/AirTable/1.0.0/getRecordById.js',
 'EXPORT/_code_engine/AirTable/1.0.0/listBases.js',
 'EXPORT/_code_engine/AirTable/1.0.0/listRecords.js',
 'EXPORT/_code_engine/AirTable/1.0.0/listRecordsWithFilter.js',
 'EXPORT/_code_engine/AirTable/1.0.0/updateRecord.js',
 'EXPORT/_code_engine/DOMO DataFlows/2.0.9/changeDataFlowOwner.js',
 'EXPORT/_code_engine/DOMO DataFlows/2.0.9/dataFlowInputDatasetSwap.js',
 'EXPORT/_code_engine/DOMO DataFlows/2.0.9/disableDataFlow.js',
 'EXPORT/_code_engine/DOMO DataFlows/2.0.9/enableDataFlow.js',
 'EXPORT/_code_engine/DOMO DataFlows/2.0.9/getDataFlowIds.js',
 'EXPORT/_code_engine/DOMO DataFlows/2.0.9/getDataFlowInputs.js',
 'EXPORT/_code_engine/DOMO DataFlows/2.0.9/getDataFlowLastRunTime.js',
 'EXPORT/_code_engine/DOMO DataFlows/2.0.9/getDataFlowMetadata.js',
 'EXPORT/_code_engine/DOMO DataFlows/2.0.9/getDataFlowOutputs.js',
 'EXPORT/_code_engine/DOMO DataFlows/2.0.9/getDataflowExecutionsStatus.js',
 'EXPORT/_code_engine/DOMO DataFlows/2.0.9/startDataFlow.js',
 'EXPORT/_code_engine/DOMO DataFlows/2.0.9/wasLastDataFlowRunSuccessful.js',
 'EXPORT/_code_engine/DOMO Awards/2.0.7/grant.js',
 'EXPORT/_code_engine/Google Analytics/1.0.0/convertValueToDate.js',
 'EXPORT/_code_engine/Google Analytics/1.0.0/getConversionRates.js',
 'EXPORT/_code_engine/Google Analytics/1.0.0/getEcommerceMetrics.js',
 'EXPORT/_code_engine/Google Analytics/1.0.0/getGoogleAnalyticsData.js',
 'EXPORT/_code_engine/Google Analytics/1.0.0/getPageViews.js',
 'EXPORT/_code_engine/Google Analytics/1.0.0/getTopPages.js',
 'EXPORT/_code_engine/Google Analytics/1.0.0/getTrafficSource.js',
 'EXPORT/_code_engine/Google Analytics/1.0.0/getUserDemographics.js',
 'EXPORT/_code_engine/Okta/1.0.0/activateUser.js',
 'EXPORT/_code_engine/Okta/1.0.0/addUserToApp.js',
 'EXPORT/_code_engine/Okta/1.0.0/addUserToGroup.js',
 'EXPORT/_code_engine/Okta/1.0.0/createUser.js',
 'EXPORT/_code_engine/Okta/1.0.0/deactivateUser.js',
 'EXPORT/_code_engine/Okta/1.0.0/deleteUser.js',
 'EXPORT/_code_engine/Okta/1.0.0/getUserId.js',
 'EXPORT/_code_engine/Okta/1.0.0/reactivateUser.js',
 'EXPORT/_code_engine/Okta/1.0.0/removeUserFromApp.js',
 'EXPORT/_code_engine/Okta/1.0.0/removeUserFromGroup.js',
 'EXPORT/_code_engine/Okta/1.0.0/suspendUser.js',
 'EXPORT/_code_engine/Okta/1.0.0/unlockUser.js',
 'EXPORT/_code_engine/Okta/1.0.0/unsuspendUser.js',
 'EXPORT/_code_engine/DOMO Start Remote Workflow/1.1.0/startWorkflowInRemoteInstance.js',
 'EXPORT/_code_engine/DOMO Start Remote Workflow/1.1.0/startWorkflowInRemoteInstanceWithJSONString.js',
 'EXPORT/_code_engine/DOMO User Governance/1.0.0/bulkUpdateUserRoles.js',
 'EXPORT/_code_engine/DOMO User Governance/1.0.0/deleteUser.js',
 'EXPORT/_code_engine/DOMO User Governance/1.0.0/getRoleIdByName.js',
 'EXPORT/_code_engine/DOMO User Governance/1.0.0/getRoleNames.js',
 'EXPORT/_code_engine/DOMO User Governance/1.0.0/getRoles.js',
 'EXPORT/_code_engine/DOMO User Governance/1.0.0/inviteUser.js',
 'EXPORT/_code_engine/DOMO User Governance/1.0.0/updateUserRole.js',
 'EXPORT/_code_engine/DOMO Card Governance/1.0.0/addCardOwners.js',
 'EXPORT/_code_engine/DOMO Card Governance/1.0.0/addCardToPages.js',
 'EXPORT/_code_engine/DOMO Card Governance/1.0.0/addSingleCardOwner.js',
 'EXPORT/_code_engine/DOMO Card Governance/1.0.0/changeCardTitle.js',
 'EXPORT/_code_engine/DOMO Card Governance/1.0.0/manageCardOwners.js',
 'EXPORT/_code_engine/DOMO Card Governance/1.0.0/removeAllUsersAndGroupsForCard.js',
 'EXPORT/_code_engine/DOMO Card Governance/1.0.0/removeCardFromAllPages.js',
 'EXPORT/_code_engine/DOMO Card Governance/1.0.0/updateCardPage.js',
 'EXPORT/_code_engine/DOMO Page Governance/1.0.0/addPageOwners.js',
 'EXPORT/_code_engine/DOMO Page Governance/1.0.0/addSinglePageOwner.js',
 'EXPORT/_code_engine/DOMO Page Governance/1.0.0/changePageTitle.js',
 'EXPORT/_code_engine/DOMO Page Governance/1.0.0/fetchAndRemovePageEntities.js',
 'EXPORT/_code_engine/DOMO Page Governance/1.0.0/makeSubPage.js',
 'EXPORT/_code_engine/DOMO Page Governance/1.0.0/managePageOwners.js',
 'EXPORT/_code_engine/Snowflake/1.0.0/asynchronousExecution.js',
 'EXPORT/_code_engine/Snowflake/1.0.0/cancelExecution.js',
 'EXPORT/_code_engine/Snowflake/1.0.0/checkExecutionStatus.js',
 'EXPORT/_code_engine/Snowflake/1.0.0/formatData.js',
 'EXPORT/_code_engine/Snowflake/1.0.0/getDataFromAsyncExecution.js',
 'EXPORT/_code_engine/Snowflake/1.0.0/queryData.js',
 'EXPORT/_code_engine/Snowflake/1.0.0/synchronousExecution.js',
 'EXPORT/_code_engine/Twilio/1.1.0/sendSMS.js',
 'EXPORT/_code_engine/Ellibot/1.0.0/myFunction.js',
 'EXPORT/_code_engine/NB AppDb/1.0.1/appendToObjectList.py',
 'EXPORT/_code_engine/NB AppDb/1.0.1/createObject.py',
 'EXPORT/_code_engine/NB AppDb/1.0.1/syncAppDB.py',
 'EXPORT/_code_engine/ejmSuperFunTestCodeEngineJS/1.0.0/doTheThing.js',
 'EXPORT/_code_engine/TestPackage/1.0.0/greeting.py',
 'EXPORT/_code_engine/Update Date Variables/1.0.0/myFunction.js',
 'EXPORT/_code_engine/NB Users and Roles/1.0.1/createUser.py',
 'EXPORT/_code_engine/NB Users and Roles/1.0.1/getRoles.py',
 'EXPORT/_code_engine/NB Users and Roles/1.0.1/get_values_from_json.py',
 'EXPORT/_code_engine/Dashboard Deduplication/1.0.0/fetchAndLogCardIds.js',
 'EXPORT/_code_engine/Dashboard Deduplication/1.0.0/updateAllCardTitles.js',
 'EXPORT/_code_engine/Dashboard Deduplication/1.0.0/updateAllCardTitlesAndDatasources.js',
 'EXPORT/_code_engine/Dashboard Deduplication/1.0.0/updateCardTitle.js',
 'EXPORT/_code_engine/testOZ/1.0.0/myFunction.js',
 'EXPORT/_code_engine/NB Authentication/1.0.1/getAuth.py',
 'EXPORT/_code_engine/NB Authentication/1.0.1/get_creds.py',
 'EXPORT/_code_engine/updateVariableFunction/1.0.0/fetchDataWithCredentials.js']
dt.datetime.now().strftime("%H:%M")
'17:51'