examples.ts contains example graphql queries and mutations for working with the IP allow list
gql-paginate.ts contains a recursive function example to paginate a graphql query with more than 100 results
| function gql(string) { | |
| return String(string).replace(`\n`, ` `) | |
| } | |
| /** | |
| * Docs: https://docs.github.com/en/graphql/reference/objects#enterprise | |
| * See 'organization' field | |
| * / | |
| const queryOrganizations = gql` | |
| query($slug: String!) { | |
| enterprise(slug: $slug) { | |
| organizations(first: 100) { | |
| totalCount | |
| nodes { | |
| id | |
| name | |
| login | |
| } | |
| } | |
| } | |
| } | |
| ` | |
| /** | |
| * Docs: https://docs.github.com/en/graphql/reference/objects#organization | |
| * See 'ipAllowListEntries' field | |
| * / | |
| const queryIPAllowEntries = gql` | |
| query($org: String! $endCursor: String) { | |
| organization(login: $org) { | |
| ipAllowListEntries(first: 100, after: $endCursor) { | |
| pageInfo { | |
| hasNextPage | |
| endCursor | |
| } | |
| nodes { | |
| allowListValue | |
| createdAt | |
| isActive | |
| name | |
| owner | |
| updatedAt | |
| } | |
| } | |
| } | |
| } | |
| ` | |
| /** | |
| * Docs: https://docs.github.com/en/graphql/reference/mutations#createipallowlistentry | |
| * / | |
| const mutationCreateIpAllowEntry = gql` | |
| mutation($ownerId: String!, $ip: String!, $name: String, $client: String) { | |
| createIpAllowListEntry( | |
| input: { | |
| ownerId: $ownerId | |
| allowListValue: $ip | |
| name: $name | |
| isActive: true | |
| clientMutationId: $client | |
| } | |
| ) { | |
| clientMutationId | |
| ipAllowListEntry { | |
| id | |
| name | |
| allowListValue | |
| createdAt | |
| updatedAt | |
| } | |
| } | |
| } | |
| ` | |
| /** | |
| * Docs: https://docs.github.com/en/graphql/reference/mutations#deleteipallowlistentry | |
| * / | |
| const mutationDeleteIpAllowEntry = gql` | |
| mutation($entryId: String!, $client: String) { | |
| deleteIpAllowListEntry( | |
| input: { ipAllowListEntryId: $entryId, clientMutationId: $client } | |
| ) { | |
| clientMutationId | |
| ipAllowListEntry { | |
| id | |
| name | |
| allowListValue | |
| createdAt | |
| updatedAt | |
| } | |
| } | |
| } | |
| ` | |
| module.exports = { | |
| queryOrganizations, | |
| mutationCreateIpAllowEntry, | |
| mutationDeleteIpAllowEntry, | |
| } |
| /** | |
| * Helper function to get the node in an object at a specific path represented | |
| * by a string. | |
| * | |
| * @export | |
| * @param {Object} object - The object to resolve the path on | |
| * @param {string} path - String path to node. Use `.` in between each path segment | |
| * @param {*} [defaultValue] - Value to return if the path can't be resolved | |
| * @returns {*} - The item at the path in the object, or defaultValue if the | |
| * path isn't resolvable | |
| */ | |
| export function resolvePath(object, path, defaultValue) { | |
| return path.split('.').reduce((o, p) => (o ? o[p] : defaultValue), object) | |
| } | |
| /** | |
| * Pull all items from a paginated GraphQL query. | |
| * | |
| * @export | |
| * @param {GraphQLClient} graphqlClient - GraphQLClient function callable with | |
| * query and variables as first and second parameters | |
| * @param {string} query - GraphQL query string. Query must includes `nodes` and | |
| * `pageInfo` containing `hasNextPage` and `endCursor` | |
| * @param {string} pathToNodes - Path to the `nodes` list where pagination is | |
| * needed to get all entries | |
| * @param {Object} queryVariables - Object with any GraphQL variables. These are | |
| * passed directly to the graphqlClient. Any variable called `after` will be overridden. | |
| * @param {string} [endCursor=null] - Used during recursion to pull the next | |
| * page. Should be null on first call to this function. | |
| * @returns {Promise<Array>} - Array of all nodes from all pages | |
| */ | |
| export async function gqlPaginate( | |
| graphqlClient, | |
| query, | |
| pathToNodes, | |
| queryVariables, | |
| endCursor = null, | |
| ) { | |
| const response = await graphqlClient(query, { | |
| ...queryVariables, | |
| after: endCursor, | |
| }) | |
| const { | |
| nodes, | |
| pageInfo: { hasNextPage, endCursor: newEndCursor }, | |
| } = resolvePath(response, pathToNodes) | |
| if (!hasNextPage) { | |
| return nodes | |
| } | |
| return [ | |
| ...nodes, | |
| ...(await gqlPaginate( | |
| graphqlClient, | |
| query, | |
| pathToNodes, | |
| queryVariables, | |
| newEndCursor, | |
| )), | |
| ] | |
| } |