Worked on pagination function

This commit is contained in:
Adina Totorean 2024-11-28 21:07:25 +02:00
parent f09091a0cb
commit e4088ca9a8
3 changed files with 24 additions and 127 deletions

View file

@ -116,45 +116,8 @@ export async function processAttributes(
return requestOptions;
}
/* Helper function to process Group/User Response */
export async function processGroupsResponse(
this: IExecuteSingleFunctions,
items: INodeExecutionData[],
response: IN8nHttpFullResponse,
): Promise<INodeExecutionData[]> {
const responseBody = response.body as { Groups: IDataObject[] };
if (!responseBody || !Array.isArray(responseBody.Groups)) {
throw new ApplicationError('Unexpected response format: No groups found.');
}
const executionData: INodeExecutionData[] = responseBody.Groups.map((group) => ({
json: group,
}));
return executionData;
}
export async function processUsersResponse(
this: IExecuteSingleFunctions,
items: INodeExecutionData[],
response: IN8nHttpFullResponse,
): Promise<INodeExecutionData[]> {
const responseBody = response.body as { Users: IDataObject[] };
if (!responseBody || !Array.isArray(responseBody.Users)) {
throw new ApplicationError('Unexpected response format: No users found.');
}
const executionData: INodeExecutionData[] = responseBody.Users.map((user) => ({
json: user,
}));
return executionData;
}
/* Helper function to handle pagination */
const possibleRootProperties = ['Attributes'];
const possibleRootProperties = ['Users', 'Groups'];
// ToDo: Test if pagination works
export async function handlePagination(
this: IExecutePaginationFunctions,
@ -163,9 +126,7 @@ export async function handlePagination(
const aggregatedResult: IDataObject[] = [];
let nextPageToken: string | undefined;
const returnAll = this.getNodeParameter('returnAll') as boolean;
let limit = 60;
// Update limit if 'returnAll' is not selected
let limit = 100;
if (!returnAll) {
limit = this.getNodeParameter('limit') as number;
resultOptions.maxResults = limit;
@ -173,49 +134,32 @@ export async function handlePagination(
resultOptions.paginate = true;
do {
console.log('----> TOKEN', nextPageToken);
if (nextPageToken) {
// Append PaginationToken to the request body
const body =
typeof resultOptions.options.body === 'object' && resultOptions.options.body !== null
? resultOptions.options.body
: {};
resultOptions.options.body = {
...body,
PaginationToken: nextPageToken,
} as IDataObject;
console.log('Updated request body with PaginationToken:', resultOptions.options.body);
resultOptions.options.qs = { ...resultOptions.options.qs, PaginationToken: nextPageToken };
console.log('----> GOT HERE');
}
// Make the request
console.log('Sending request with options:', resultOptions);
const responseData = await this.makeRoutingRequest(resultOptions);
// Process response data
for (const page of responseData) {
console.log('Processing page:', page.json);
// Iterate over possible root properties (e.g., "Users")
for (const prop of possibleRootProperties) {
if (page.json[prop]) {
const currentData = page.json[prop] as IDataObject[];
console.log(`Extracted data from property "${prop}":`, currentData);
aggregatedResult.push(...currentData);
}
}
// Check if the limit has been reached
if (!returnAll && aggregatedResult.length >= limit) {
console.log('Limit reached. Returning results.');
return aggregatedResult.slice(0, limit).map((item) => ({ json: item }));
}
// Update the nextPageToken for the next request
nextPageToken = page.json.PaginationToken as string | undefined;
console.log('Next Page Token:', nextPageToken);
}
} while (nextPageToken);
console.log('----> Array with results', aggregatedResult);
console.log('Final Aggregated Results:', aggregatedResult);
return aggregatedResult.map((item) => ({ json: item }));
}

View file

@ -1,7 +1,7 @@
import type { IExecuteSingleFunctions, IHttpRequestOptions, INodeProperties } from 'n8n-workflow';
import { NodeOperationError } from 'n8n-workflow';
import { handleErrorPostReceive, processGroupsResponse } from '../GenericFunctions';
import { handleErrorPostReceive, handlePagination } from '../GenericFunctions';
export const groupOperations: INodeProperties[] = [
{
@ -83,9 +83,8 @@ export const groupOperations: INodeProperties[] = [
value: 'getAll',
description: 'Retrieve a list of groups',
routing: {
send: {
paginate: true,
},
send: { paginate: true },
operations: { pagination: handlePagination },
request: {
method: 'POST',
headers: {
@ -98,7 +97,7 @@ export const groupOperations: INodeProperties[] = [
ignoreHttpStatusErrors: true,
},
output: {
postReceive: [handleErrorPostReceive, processGroupsResponse],
postReceive: [handleErrorPostReceive],
},
},
action: 'Get many groups',
@ -580,38 +579,20 @@ const getAllFields: INodeProperties[] = [
name: 'returnAll',
default: false,
description: 'Whether to return all results or only up to a given limit',
displayOptions: {
show: {
resource: ['group'],
operation: ['getAll'],
},
},
displayOptions: { show: { resource: ['group'], operation: ['getAll'] } },
type: 'boolean',
},
{
displayName: 'Limit',
name: 'limit',
default: 50,
description: 'Max number of results to return',
displayOptions: {
show: {
resource: ['group'],
operation: ['getAll'],
returnAll: [false],
},
},
routing: {
send: {
property: '$top',
type: 'query',
value: '={{ $value }}',
},
},
required: true,
type: 'number',
typeOptions: {
minValue: 1,
},
validateType: 'number',
default: 20,
description: 'Max number of results to return',
displayOptions: { show: { resource: ['group'], operation: ['getAll'], returnAll: [false] } },
},
{
displayName: 'User Pool ID',

View file

@ -5,7 +5,6 @@ import {
handlePagination,
presendFilter,
processAttributes,
processUsersResponse,
} from '../GenericFunctions';
export const userOperations: INodeProperties[] = [
@ -106,9 +105,8 @@ export const userOperations: INodeProperties[] = [
value: 'getAll',
description: 'Retrieve a list of users',
routing: {
send: {
paginate: true,
},
send: { paginate: true },
operations: { pagination: handlePagination },
request: {
method: 'POST',
headers: {
@ -121,7 +119,7 @@ export const userOperations: INodeProperties[] = [
ignoreHttpStatusErrors: true,
},
output: {
postReceive: [handleErrorPostReceive, processUsersResponse],
postReceive: [handleErrorPostReceive],
},
},
action: 'Get many users',
@ -627,46 +625,20 @@ const getAllFields: INodeProperties[] = [
name: 'returnAll',
default: false,
description: 'Whether to return all results or only up to a given limit',
displayOptions: {
show: {
resource: ['user'],
operation: ['getAll'],
},
},
routing: {
send: {
paginate: '={{ $value }}',
},
operations: {
pagination: handlePagination,
},
},
displayOptions: { show: { resource: ['user'], operation: ['getAll'] } },
type: 'boolean',
},
{
displayName: 'Limit',
name: 'limit',
default: 50,
description: 'Max number of results to return',
displayOptions: {
show: {
resource: ['user'],
operation: ['getAll'],
returnAll: [false],
},
},
routing: {
send: {
property: 'limit',
type: 'body',
value: '={{ $value }}',
},
},
required: true,
type: 'number',
typeOptions: {
minValue: 1,
},
validateType: 'number',
default: 20,
description: 'Max number of results to return',
displayOptions: { show: { resource: ['user'], operation: ['getAll'], returnAll: [false] } },
},
{
displayName: 'Additional Fields', // ToDo: Test additional parameters with the API